01背包双向遍历[以及一些注意事项]
01背包双向遍历
USACO03FALL]Cow Exhibition G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 因为有负权状态的存在所以在转移的时候需要整体偏移一个最大值,这样就不会越界了
- 因为有负权状态的存在,所以在转移的时候不能从前往后转移了,因为这样会不停的接替
- 需要分类讨论正权与负权的情况
- 有两个状态,可以用状态携带一个变量,再用value携带一个变量
const int N=410;
const int MR=400000;
int n,m;
int a[N],b[N];
int dp[MR*2+20];
void solve(){
//try it again.
cin>>n;
up(1,n)cin>>a[o]>>b[o];
memset(dp,~0x3f3f3f3f,sizeof(dp));
dp[MR]=0;
up(1,n){
if(a[o]>0){
for(int j=MR;j>=-MR;j--){
if(-MR<=j-a[o]&&j-a[o]<=MR)dp[j+MR]=max(dp[j+MR],dp[j+MR-a[o]]+b[o]);
}
}
else{
for(int j=-MR;j<=MR;j++){
if(-MR<=j-a[o]&&j-a[o]<=MR)dp[j+MR]=max(dp[j+MR],dp[j+MR-a[o]]+b[o]);
}
}
}
int ans=0;
up(0,MR){
if(dp[o+MR]>=0){
ans=max(ans,dp[o+MR]+o);
}
}
cout<<ans<<endl;
}

浙公网安备 33010602011771号