您的位置:首页 > 其它

LightOJ 1231 Coin Change (I)(部分背包)

2016-03-22 22:15 423 查看
B - Coin Change (I)
Time Limit:1000MS Memory Limit:32768KB
64bit IO Format:%lld & %llu
Submit
Status
Practice
LightOJ 1231

Description

In a strange shop there are n types of coins of value
A1, A2 ... An
. C1, C2, ... Cn denote the number of coins of valueA1, A2 ... An respectively. You have to find the number
of ways you can makeK using the coins.

For example, suppose there are three coins 1, 2, 5 and we can use coin 1 at most 3 times, coin 2 at most 2 times and coin 5 at most 1 time. Then ifK = 5 the possible ways are:

1112

122

5

So, 5 can be made in 3 ways.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing two integers n (1 ≤ n ≤ 50) andK (1 ≤ K ≤ 1000). The next line contains
2n integers, denotingA1, A2 ... An, C1, C2 ... Cn (1 ≤ Ai ≤ 100, 1 ≤ Ci ≤ 20). AllAi will be distinct.

Output

For each case, print the case number and the number of ways K can be made. Result can be large, so, print the result modulo100000007.

Sample Input

2

3 5

1 2 5 3 2 1

4 20

1 2 3 4 8 4 2 1

Sample Output

Case 1: 3

Case 2: 9

对于dp的思想还是不懂,对于背包问题更是理解不透彻,既然发现了这一点就要赶紧完善自己!!

这是背包题目要对物品种类,背包数量,物品的个数一一枚举,根据剩余的背包空间进行下一步

思路:dp[i][j]+=dp[i-1][j-k*a[i]];

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[55][1005];//根据k的范围定义dp的数组
int main()
{
int t,n,k,a[55],b[55],m=1;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
//
memset(dp,0,sizeof(dp));
dp[0][0]=1;
//控制输出格式
if(m++)
cout<<"Case "<<m-1<<": ";

for(int i=1;i<=n;i++)//枚举物品种类
{
for(int j=0;j<=k;j++)//枚举背包数量
for(int k=1;k<=b[i];k++)//枚举物品的个数
if(j-k*a[i]>=0)//判断背包当前是否可以继续放物品
dp[i][j]+=dp[i-1][j-k*a[i]];
for(int h=0;h<=k;h++)
dp[i][h]=(dp[i][h]+dp[i-1][h])%100000007;
}
printf("%d\n",dp
[k]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: