ACM-ICPC 2018 焦作赛区网络预赛 K.Transport Ship(01背包求方案数)

ACM-ICPC 2018 焦作赛区网络预赛 K.Transport Ship(01背包求方案数)_第1张图片

 

样例输入

1
1 2
2 1
1
2

样例输出

0
1

题意:  有n种船,第i船能载v[i]重量的货物,有(2^c[i])-1 艘第i种船,有q个询问 每个询问问你正好装s重量的货物的方案数(每艘船要装满)

思路:题目中 每种船的个数是关键。 对于 (2^c[i])-1 艘船  可以分为 2^0+2^1+2^2+...+2^(c[i]-1)     如果我们将每项分开当成一个单独的物品   通过选择其中的某几项 可以拼出任意小于 (2^c[i])-1的数  (也就是二进制表示十进制) 那么现在所以物品的数量都为一个  就可以用01背包求方案数 预处理出所有S的答案

我第一次遇到用背包求方案数的    dp[i][j] 表示用前i个物品达到重量为j

如果是求最大价值 dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]) 

方案数为 dp[i][j]=dp[i-1][j]+dp[i-1][j-v[i]]

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod= 1e9+7;
ll v[25];
ll c[25];
ll dp[10005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n,q;
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        scanf("%d%d",&n,&q);
        for(int i=0;i=val;k--){
                    dp[k]+=dp[k-val];
                    dp[k]%=mod;
                }
            }
        }
        while(q--){
            int s;
            scanf("%d",&s);
            printf("%lld\n",dp[s]);
        }
    }
    return 0;
}

 

你可能感兴趣的:(动态规划)