DP的数组偏移

题目链接

学到了一种方法,可以处理背包问题中带负数的转移

代码挺容易的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,a[403],b[403],f[800003],ans,sum;
inline int rd()
{
	int x=0,p=1;
	char a=getchar();
	while((a<48||a>57)&&a!='-')
		a=getchar();
	if(a=='-')
		p=-p,a=getchar();
	while(a>47&&a<58)
		x=(x<<1)+(x<<3)+(a&15),a=getchar();
	return x*p;
}
int main()
{
	n=rd();
	for(int i=1; i<=n; i++)
		a[i]=rd(),b[i]=rd();
	for(int i=1; i<=n; i++)
		if(a[i]>0)
			sum+=a[i];
	sum*=2;
	for(int i=0; i<=sum; i++)
		f[i]=-1e9;
	f[sum/2]=0;
	for(int i=1; i<=n; i++)
	{
		if(a[i]>=0)
			for(int j=sum; j>=a[i]; j--)
				f[j]=max(f[j],f[j-a[i]]+b[i]);
		else
			for(int j=0; j<=sum+a[i]; j++)
				f[j]=max(f[j],f[j-a[i]]+b[i]);
	}
	for(int i=sum/2; i<=sum; i++)
		if(f[i]>0)
			ans=max(ans,f[i]+i-sum/2);
	cout<<ans;
	return 0;
}
posted @ 2019-11-27 23:43  dz_ice  阅读(162)  评论(0编辑  收藏  举报