近期crq老师为了提高各个学生对ACM的兴趣,在TOJ上增加了积分制度和礼品兑换功能, TOJ的积分是来之不易的,固然同学们都想用同一积分换取最大价值的礼品,某同学用了M的积分换取了一些礼品。 请问:他用M的积分最多能换取多少价值的礼品呢? (积分M一定要使用完)
输入
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数M和N(1<=M<=1000,1<=N<=100),分别表示换取的总积分和礼品的种类,然后是N行数据,每行包含3个数p,h和c(1<=p<=100,0<=h<=200,1<=c<=1000),分别表示每种礼品的价格、对应种类礼品的剩余数目以及每类礼品的消耗的积分。
输出
对于每组测试数据,如果M能使用完请输出"The maximum value is X." ,否则输出"This is impossible.".你可以假设同一类物品能多次换取。每个实例的输出占一行。

1 #include <bits/stdc++.h> 2 using namespace std; 3 int t,n,m; 4 int f[1005]; 5 const int INF=0x3f3f3f3f; 6 struct Node{ 7 int w,v; 8 }; 9 vector<Node> vec; 10 int main() 11 { 12 ios::sync_with_stdio(false); 13 cin>>t; 14 while(t--){ 15 vec.clear(); 16 for(int i=1;i<=1004;i++) f[i]=-INF; 17 f[0]=0; 18 cin>>n>>m; 19 for(int i=1,p,h,c;i<=m;i++){ 20 cin>>p>>h>>c; 21 int sum=0; 22 for(int j=1;j<=h;j*=2){ 23 h-=j; 24 vec.push_back({j*p,c*j}); 25 } 26 if(h>0) 27 vec.push_back({h*p,h*c}); 28 } 29 for(auto X:vec){ 30 for(int i=n;i>=X.v;i--){ 31 if(f[i-X.v]!=-INF) 32 f[i]=max(f[i],f[i-X.v]+X.w); 33 } 34 } 35 if(f[n]==-INF) cout << "This is impossible." << endl; 36 else{ 37 cout << "The maximum value is "; 38 cout << f[n] << "." << endl; 39 } 40 } 41 return 0; 42 }
样例输入
样例输出
解题思路:多重背包恰好装满