题意:
给定两串数字,有正有服,求出最大和,且这个和的状态下满足任一边都不为负。
思路:
dp。
说是背包,但是其实完全不懂背包的也可以做出来。
本质就是用dp数组来记录状态,然后依次增加状态和更新而已。。
值得注意的就是对负值平移成非负的。
linux环境下vim编辑器a掉的第二道题,很艰难,没少gdb。
强烈意识到要开始改装一下vim成ide了,利其器。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=105;
const int ost=100000;
const int inf=(1<<30);
int n,m;
int d[2*ost+5];
struct Node
{
int s,f;
}a[N];
void solve()
{
memset(d,0,sizeof(d));
d[ost]=ost;
int l=ost,r=ost;
for(int i=1;i<=n;i++)
{
int s=a[i].s;
int f=a[i].f;
if(s>0)
{
for(int j=r;j>=l;j--)
{
if(d[j])
{
d[j+s]=Max(d[j]+f,d[j+s]);
r=Max(r,j+s);
}
}
}
else
{
for(int j=l;j<=r;j++)
{
if(d[j])
{
d[j+s]=Max(d[j]+f,d[j+s]);
l=Min(j+s,l);
}
}
}
}
int ans=0;
for(int i=ost;i<=r;i++)
if(d[i]&&d[i]>=ost)
{
ans=Max(ans,d[i]+i-2*ost);
}
printf("%d\n",ans);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].s,&a[i].f);
}
solve();
return 0;
}