题意:
给定两串数字,有正有服,求出最大和,且这个和的状态下满足任一边都不为负。
思路:
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; }