時間長不寫代碼,感覺變菜了。
整體優化思路和快速冪很相近
如果第i個物品有num[i]個,花費是 c[i] , 價值是 v[i]
那麼我們可以把它拆分成數個物品。
比如14
1 2 4 7
就可以把14個相同物品看成 4 個不同的物品,但是他們在一起可以組成
1-14,
所以只要對這四個物品跑0-1揹包得到的答案就是對的
# include <cstdio>
# include <cmath>
# include <algorithm>
using namespace std;
const int maxn = 1e5+10;
int c[maxn],v[maxn],num[maxn];
int dp[maxn];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i++)
{
scanf("%d %d %d",&c[i],&v[i],&num[i]);
}
for(int i = 1;i <= n;i++)
{
int k = 1;
while(num[i] >= k || num[i] > 0){
if(num[i] < k) k = num[i];
int cost = k*c[i];
int value = k*v[i];
for(int j = m;j >= cost;j--)
{
dp[j] = max(dp[j],dp[j-cost]+value);
}
num[i] -= k;
k *= 2;
}
}
printf("%d\n",dp[m]);
return 0;
}