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

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[n][k]);
    }
    return 0;
}



你可能感兴趣的:(背包,lightoj)