【动态规划】Gym - 101102A - Coins

Hasan and Bahosain want to buy a new video game, they want to share the expenses. Hasan has a set of N coins and Bahosain has a set of M coins. The video game costs W JDs. Find the number of ways in which they can pay exactly W JDs such that the difference between what each of them payed doesn’t exceed K.

In other words, find the number of ways in which Hasan can choose a subset of sum S1and Bahosain can choose a subset of sum S2 such that S1?+?S2?=?W and |S1?-?S2|?≤?K.

Input

The first line of input contains a single integer T, the number of test cases.

The first line of each test case contains four integers NMK and W (1?≤?N,?M?≤?150) (0?≤?K?≤?W) (1?≤?W?≤?15000), the number of coins Hasan has, the number of coins Bahosain has, the maximum difference between what each of them will pay, and the cost of the video game, respectively.

The second line contains N space-separated integers, each integer represents the value of one of Hasan’s coins.

The third line contains M space-separated integers, representing the values of Bahosain’s coins.

The values of the coins are between 1 and 100 (inclusive).

Output

For each test case, print the number of ways modulo 109?+?7 on a single line.

Example

Input

24 3 5 182 3 4 110 5 52 1 20 2010 3050

Output

20

对A和B的硬币分别dp,f[i]表示拼成i元的方案数,for i=1 to n for j=15000 down to 0 f(j+a(i))+=f(j)

最后枚举一下差在K以内,且i+j=W的f(i)和g(j)即可。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
#define MOD 1000000007ll
int T,n,m,K,W;
int a[160],b[160];
int Abs(int x)
{
	return x<0 ? (-x) : x;
}
ll f[15010],g[15010];
int main()
{
	scanf("%d",&T);
	for(;T;--T)
	  {
	  	scanf("%d%d%d%d",&n,&m,&K,&W);
		for(int i=1;i<=n;++i)
	  	  scanf("%d",&a[i]);
		for(int i=1;i<=m;++i)
	  	  scanf("%d",&b[i]);
	  	memset(f,0,sizeof(f));
	  	memset(g,0,sizeof(g));
	  	f[0]=1;
	  	for(int i=1;i<=n;++i)
	  	  for(int j=15000;j>=0;--j)
	  	    if(a[i]+j<=15000)
	  	      f[j+a[i]]=(f[j+a[i]]+f[j])%MOD;
	  	g[0]=1;
	  	for(int i=1;i<=m;++i)
	  	  for(int j=15000;j>=0;--j)
	  	    if(b[i]+j<=15000)
	  	      g[j+b[i]]=(g[j+b[i]]+g[j])%MOD;
	  	ll ans=0;
	  	for(int i=0;i<=W;++i)
	  	  if(Abs(W-i-i)<=K)
	  	    ans=(ans+f[i]*g[W-i]%MOD)%MOD;
	  	cout<<ans<<endl;
	  }
	return 0;
}
时间: 2024-08-03 12:16:29

【动态规划】Gym - 101102A - Coins的相关文章

codeforce Gym 101102A Coins (01背包变形)

01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXW 15005 #define N 155 #define LL long long #define MOD 1000000007 int w1[N],w2[N]; LL dp1[MAXW],dp2[MAXW]; int main(

ACM: Gym 101047M Removing coins in Kem Kadr&#227;n - 暴力

Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Practice Description standard input/output Andréh and his friend Andréas are board-game aficionados. They know many of their friends

【DFS】【拓扑排序】【动态规划】Gym - 100642A - Babs&#39; Box Boutique

给你10个箱子,有长宽高,每个箱子你可以决定哪个面朝上摆.把它们摞在一起,边必须平行,上面的不能突出来,问你最多摆几个箱子. 3^10枚举箱子用哪个面.然后按长为第一关键字,宽为第二关键字,从大到小排序. 如果前面的宽大于等于后面的宽,就连接一条边. 形成一张DAG,拓扑排序后跑最长路即可. #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespa

CodeForces Gym 101047M Removing coins in Kem Kadr&#227;n 暴力

Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 101047M Description standard input/output Andréh and his friend Andréas are board-game aficionados. They know many of their friends would lo

Gym 100829S_surf 动态规划的优化

题目大意是,非你若干个任务,任务分别对应开始时间.预期收益.持续时间三项指标,让你从中选择一个受益最大的方案(没有开始时间相同的任务). 于是,标准状态转移方程应当为,设DP[K]为选择了前K个任务的最大收益,后面转移为DP[K+1]=MAX且能够共存的(DP[I]):很容易想到N^2的暴力更新,但是这题数量太大,会炸得连渣都不剩.于是需要优化到较低的数量级(比如NLOGN) 注意到,我们也许不用对某个任务来选取前K个的最大值,不容易想到优化但是想想刘汝佳同志的话--不方便直接求解的时候想想更新

poj 1742 Coins (动态规划,背包问题)

Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 32977   Accepted: 11208 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some

抛硬币 Flipping Coins(Gym - 101606F)

Here's a jolly and simple game: line up a row of N identical coins, all with the heads facing down onto the table and the tails upwards, and for exactly K times take one of the coins, toss it into the air, and replace it as it lands either heads-up o

POJ1742 coins 动态规划之多重部分和问题

原题链接:http://poj.org/problem?id=1742 题目大意:tony现在有n种硬币,第i种硬币的面值为A[i],数量为C[i].现在tony要使用这些硬币去买一块价格不超过m的表.他希望买的时候不用找零,问有多少种价格能满足这一点. 这个问题实际上是一个多重部分和的问题:假设有n种物品,每种物品的价值为v[i],数量为c[i],随意选取这些物品,能否使它们的价值之和恰好为m.使用动态规划的思想来求解这类问题: 定义dp数组,dp[i][j]的值代表前i种物品随意选取,价值之

Codeforces Gym 101623A - 动态规划

题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分. 我们将这个序列排序,对于权值相同的一段数可以任意交换它们,每两个相邻数在原序列的位置中如果是$i, i + 1$,那么划分的段数就可以减少1. 每次转移我们考虑添加值相同的一段. 每次转移能不能将减少的段数加一取决于当前考虑的数在前一段内有没有出现以及有没有作为最左端点. 因此我们记录一个决策与