题目描述
终于,破解了千年的难题。小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎。但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物。看来小FF只能含泪舍弃其中的一部分宝物了……小FF对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小FF有一个最大载重为W的采集车,洞穴里总共有n种宝物,每种宝物的价值为v[i],重量为w[i],每种宝物有m[i]件。小FF希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大。
输入格式
第一行为一个整数N和w,分别表示宝物种数和采集车的最大载重。
接下来n行每行三个整数,其中第i行第一个数表示第i类品价值,第二个整数表示一件该类物品的重量,第三个整数为该类物品数量。
输出格式
输出仅一个整数ans,表示在采集车不超载的情况下收集的宝物的最大价值。
==============================================================================================================================================================
一些遇到的问题
对于二进制的理解。
不是完全背包,考虑越界问题。
M=10,c[i]=3,s[i]=26
1*
2*
4(x) 但是for循环从10->12所以不循环了。
以此类推一直搞到24,碰到边界,回到2。
假如还爆,那继续不循环
得了,我看见22行的问题了。草dp[j-c[i]]*k -> dp[j-c[i]*k]
还错。
/*15:41*/
问题出在二进制倍增何时越界。
假定s[i]==13;
1 2 4 6
4个数字可以构成1-13内的所有数字,故可完成化简01背包问题。
若是1 2 4……2^n可以组成2^(n+1)-1内的所有数字。
所以1-7可以通过这样组成。
所以把剩下的系数得6。就扩充到1-13;
注意:k循环完后自乘
也就是k*2-1<=s[i]可以循环。 //我刚刚真是天才
譬如 1,2,4
结束后为8,如果动8,那么就满足15了。显然不需要满足15。所以k*2-1>s[i]了,就不用循环了。
/*16:25*/
#include <bits/stdc++.h> #define MAXN 101 #define MAXM 40001 using namespace std; int v[MAXN],c[MAXN],s[MAXN],dp[MAXM]; int main() { int n,m; cin>>n>>m; for (int i=1;i<=n;i++) cin>>v[i]>>c[i]>>s[i]; for (int i=1;i<=n;i++) { int k=1; for (k=1;k*2<s[i];k=k*2) { for (int j=m;j>=c[i]*k;j--) dp[j]=max(dp[j],dp[j-c[i]*k]+v[i]*k); } k--; k=s[i]-k; if (k!=0) { for (int j=m;j>=c[i]*k;j--) dp[j]=max(dp[j],dp[j-c[i]*k]+v[i]*k); } } cout<<dp[m]; return 0; }