NOI 2013 书法家
我真是日狗了。。。。。。
果然还是没有耐心读题,搞到读题读错了2个地方,结果调试了半天。。。。。。
言归正传。
动态规划。
这种题目很常见。
我们发现竖着做比较麻烦,那么可以横着做。
打竖将"NOI“分成11种类型。
F[i][j][k][l]表示第i列的涂色部分的上边界为j,下边界为k,类型为l。
然后转移。
从2类型->2类型有点麻烦,我们可以借组一个辅助数组b,见程序注释部分。
#include<cstdio> #include<cstdlib> #include<iostream> #include<fstream> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<utility> #include<set> #include<bitset> #include<vector> #include<functional> #include<deque> #include<cctype> #include<climits> #include<complex> //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL; typedef double DB; typedef pair<int,int> PII; typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a)) #define mmcy(a,b) memcpy(a,b,sizeof(a)) #define re(i,a,b) for(i=a;i<=b;i++) #define red(i,a,b) for(i=a;i>=b;i--) #define fi first #define se second #define m_p(a,b) make_pair(a,b) #define SF scanf #define PF printf #define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;} template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;} template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-9; inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;} const DB Pi=acos(-1.0); inline void clear(vector<int> *A,int a,int b){int i,j;A->clear();re(i,0,a)re(j,0,b)A[i].push_back(0);} inline int gint() { int res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } inline LL gll() { LL res=0;bool neg=0;char z; for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar()); if(z==EOF)return 0; if(z=='-'){neg=1;z=getchar();} for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar()); return (neg)?-res:res; } const int maxN=150; const int maxM=500; const int INF=1073741824; int N,M; int mp[maxN+10][maxM+10]; int sum[maxM+10][maxN+10]; int x,y,F[2][maxN+10][maxN+10][15]; int ans; inline int ask(int r,int x,int y){return sum[r][y]-sum[r][x-1];} int b[maxN+10]; inline void clear(int x){int j,k,l;re(j,0,N+1)re(k,0,N+1)re(l,0,11+3) F[x][j][k][l]=-INF;} int main() { freopen("penman.in","r",stdin); freopen("penman.out","w",stdout); int i,j,k; N=gint();M=gint(); re(i,1,N)re(j,1,M)mp[i][j]=gint(); re(i,1,M)re(j,1,N)sum[i][j]=sum[i][j-1]+mp[j][i]; x=1;y=0; clear(y); re(j,1,N)re(k,j,N)F[y][j][k][1]=ask(1,j,k); ans=-INF; re(i,2,M) { int t; swap(x,y); clear(y); //1 re(j,1,N)re(k,j,N) { upmax(F[y][j][k][1],F[x][j][k][1]+ask(i,j,k)); upmax(F[y][j][k][1],ask(i,j,k)); } //2 re(j,1,N) { t=F[x][j][N][1]; red(k,N-1,j) { upmax(F[y][j][k][2],t+ask(i,j,k)); upmax(t,F[x][j][k][1]); } } /* (1) l=j r=j..k */ re(j,1,N) { t=-INF; re(k,j,N) { upmax(t,F[x][j][k][2]); upmax(F[y][j][k][2],t+ask(i,j,k)); } } /* (2) re(l,1,j-1) re(r,j-1,k) F[i-1][l][r][2] b[r]表示F[i-1][1..j-1][r][2]的最大值,b[r]随着j的递增的递增 求b[j-1...k]的最大值 */ re(j,0,N+1)b[j]=-INF; re(j,1,N) { t=-INF; re(k,j-1,N) { upmax(b[k],F[x][j-1][k][2]); upmax(t,b[k]); if(k>=j) upmax(F[y][j][k][2],t+ask(i,j,k)); } } /*int l,r; re(j,1,N)re(k,j,N)re(l,j,j)re(r,j,k)upmax(F[y][j][k][2],F[x][l][r][2]+ask(i,j,k)); re(j,1,N)re(k,j,N)re(l,1,j-1)re(r,j-1,k)upmax(F[y][j][k][2],F[x][l][r][2]+ask(i,j,k));*/ //3 re(j,1,N)re(k,j,N)upmax(F[y][j][k][3],F[x][j][k][3]+ask(i,j,k)); re(k,1,N) { t=F[x][k][k][2]; red(j,k-1,1) { upmax(F[y][j][k][3],t+ask(i,j,k)); upmax(t,F[x][j][k][2]); } } //4 re(j,1,N)re(k,j,N)upmax(F[y][j][k][4],F[x][j][k][4]); t=-INF; re(j,1,N) re(k,j,N) upmax(t,F[x][j][k][3]); re(j,1,N)re(k,j,N)upmax(F[y][j][k][4],t); //5 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][5],F[x][j][k][4]+ask(i,j,k)); } //6 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][6],F[x][j][k][6]+ask(i,j,j)+ask(i,k,k)); upmax(F[y][j][k][6],F[x][j][k][5]+ask(i,j,j)+ask(i,k,k)); } //7 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][7],F[x][j][k][6]+ask(i,j,k)); } //8 re(j,1,N)re(k,j,N)upmax(F[y][j][k][8],F[x][j][k][8]); t=-INF; re(j,1,N)re(k,j+2,N)upmax(t,F[x][j][k][7]); re(j,1,N)re(k,j,N)upmax(F[y][j][k][8],t); //9 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][9],F[x][j][k][9]+ask(i,j,j)+ask(i,k,k)); upmax(F[y][j][k][9],F[x][j][k][8]+ask(i,j,j)+ask(i,k,k)); } //10 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][10],F[x][j][k][10]+ask(i,j,k)); upmax(F[y][j][k][10],F[x][j][k][9]+ask(i,j,k)); } //11 re(j,1,N)re(k,j+2,N) { upmax(F[y][j][k][11],F[x][j][k][11]+ask(i,j,j)+ask(i,k,k)); upmax(F[y][j][k][11],F[x][j][k][10]+ask(i,j,j)+ask(i,k,k)); upmax(ans,F[y][j][k][11]); } } cout<<ans<<endl; return 0; }