题意
种物品,每种物品有
个,体积
,价值
,背包体积
,求最大价值
思路
- 可以把每个物品直接放
次,转化为01背包,大数据会TLE
- 打包-二进制优化:显然,每个数n可以拆成所有不大于它的二进制次方组合+剩余部分,如此便可表示从0~n,所以对每个
进行拆分,从1开始,不断拆分,直到拆不出来,就把剩下的打包为一堆,优化后仍然是一个01背包
AC代码
#include<bits/stdc++.h>
#define pii pair<int,int>
#define se second
#define fi first
using namespace std;
int dp[202020];
int x[200],vol[200],val[200];
vector<pii> vv;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,T;
cin >> n >> T ;
for(int i=1;i<=n;i++){
cin >> x[i] >> vol[i] >> val[i] ;
}
//pack
vv.push_back({0,0});
for(int i=1;i<=n;i++){
int tp=1;
while(x[i]-tp>=0){
x[i]-=tp;
vv.push_back({tp*vol[i],tp*val[i]});
tp<<=1;
}
if(x[i]) vv.push_back({x[i]*vol[i],x[i]*val[i]});
}
int sz=vv.size();
for(int i=1;i<sz;i++){
for(int j=T;j>=vv[i].fi;j--){
dp[j]=max(dp[j],dp[j-vv[i].fi]+vv[i].se);
}
}
cout << dp[T] << endl ;
return 0;
}