Backpack deformation.
The operations are divided into two categories, which can be handled separately.
can be DP processing out L[I]:L[I]=-1 representative from left to right I length can not be pieced together, L[i]!=-1 said from left to right I length could be pieced together, and the minimum cost is l[i].
The inverse of the DP can be processed out of the R[i]:r[i]=-1 representative from right to left n+1-i length can not be pieced together, R[i]!=-1 said from right to left n+1-i length could be pieced together, and the minimum cost is r[i].
From l[1---i] and r[i+1---n] can be obtained, with I as the optimal solution of the division, so, enumeration I can be.
#pragmaComment (linker, "/stack:1024000000,1024000000")#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<Set>#include<queue>#include<stack>#include<iostream>using namespaceStd;typedefLong LongLL;Const DoublePi=acos (-1.0), eps=1e-8;voidFile () {freopen ("D:\\in.txt","R", stdin); Freopen ("D:\\out.txt","W", stdout);} InlineintRead () {Charc = GetChar (); while(!isdigit (c)) C =GetChar (); intx =0; while(IsDigit (c)) {x = x *Ten+ C-'0'; c =GetChar ();} returnx;}Const intmaxn= ++Ten;intt,n,m;structXintop,a,x;} S[MAXN];BOOLCMP1 (X A,ConstX b) {returna.a<B.A;}BOOLCMP2 (X A,ConstX b) {returnA.a>B.A;}intL[MAXN],R[MAXN];intMain () {scanf ("%d", &t);intcas=1; while(t--) {scanf ("%d%d",&n,&m); for(intI=1; i<=m;i++) scanf ("%d%d%d",&s[i].op,&s[i].a,&s[i].x); Sort (S+1, s+1+M,CMP1); memset (L,-1,sizeofL); l[0]=0; for(intI=1; i<=m;i++) { if(s[i].op!=1)Continue; for(intj=n;j>=0; j--) { if(l[j]==-1)Continue;if(J+S[I].X>S[I].A)Continue; if(l[j+s[i].x]==-1) l[j+s[i].x]=l[j]+1; ElseL[j+s[i].x]=min (l[j+s[i].x],l[j]+1); }} memset (R,-1,sizeofR); r[n+1]=0; Sort (S+1, s+1+M,CMP2); for(intI=1; i<=m;i++) { if(s[i].op!=2)Continue; for(intj=1; j<=n+1; j + +) { if(r[j]==-1)Continue;if(J-S[I].X<S[I].A)Continue; if(r[j-s[i].x]==-1) r[j-s[i].x]=r[j]+1; ElseR[j-s[i].x]=min (r[j-s[i].x],r[j]+1); } } intans1=0, ans2=0; for(intI=0; i<=n;i++) { inta1=0, a2=0, b1=0, b2=0; for(intj=i;j>=0; j--) {if(l[j]==-1)Continue; A1=J,A2=L[J]; Break; } for(intj=i+1; j<=n+1; j + +) {if(r[j]==-1)Continue; b1=n+1-J,B2=R[J]; Break; } if(a1+b1>ans1) ANS1=A1+B1, ans2=a2+B2; Else if(a1+b1==ans1) Ans2=min (ans2,a2+B2); } printf ("Case %d:%d%d\n", cas++, ANS1,ANS2); } return 0;}
HDU 4381 Grid