01背包双向遍历[以及一些注意事项]

01背包双向遍历

USACO03FALL]Cow Exhibition G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  1. 因为有负权状态的存在所以在转移的时候需要整体偏移一个最大值,这样就不会越界了
  2. 因为有负权状态的存在,所以在转移的时候不能从前往后转移了,因为这样会不停的接替
  3. 需要分类讨论正权与负权的情况
  4. 有两个状态,可以用状态携带一个变量,再用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;
}
posted @ 2023-03-12 00:32  liangqianxing  阅读(17)  评论(0)    收藏  举报