只贴代码:
View Code
#include <algorithm> #include <iostream> #include <limits.h> #include <cstdlib> #include <cstring> #include <cstdio> #include <queue> #include <stack> #include <cmath> #include <map> #include <set> using namespace std; const int maxn=105; const int maxm=10000+5; const int INF=0x3fffffff; int n,m,x,t; int val[maxn][maxm],sum[maxn][maxm],dp[maxn][maxm]; int que[maxm],lq[maxm],rq[maxm]; void init() { for(int i=1;i<=n+1;i++) { for(int j=1;j<=m;j++) { sum[i][j]=0; dp[i][j]=-INF; val[i][j]=0; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&val[i][j]); sum[i][j]=sum[i][j-1]+val[i][j]; } } int ss=0; for(int i=x;i>=x-t;i--) { ss+=val[1][i]; dp[1][i]=ss; dp[2][i]=dp[1][i]+val[2][i]; } ss=0; for(int i=x;i<=x+t;i++) { ss+=val[1][i]; dp[1][i]=ss; dp[2][i]=dp[1][i]+val[2][i]; } } void DP() { for(int i=3;i<=n+1;i++) { for(int j=1;j<=m;j++) { lq[j]=dp[i-1][j]-sum[i-1][j]; rq[j]=dp[i-1][j]+sum[i-1][j-1]; } int head,tail; head=1,tail=0; for(int j=1;j<=m;j++) { while(head<=tail&&lq[que[tail]]<=lq[j]) tail--; que[++tail]=j; while(head<=tail&&que[head]<j-t) head++; dp[i][j]=max(dp[i][j],lq[que[head]]+sum[i-1][j]+val[i][j]); } head=1,tail=0; for(int j=m;j>=1;j--) { while(head<=tail&&rq[que[tail]]<=rq[j]) tail--; que[++tail]=j; while(head<=tail&&que[head]>j+t) head++; dp[i][j]=max(dp[i][j],rq[que[head]]-sum[i-1][j-1]+val[i][j]); } } int ans=-INF; for(int j=1;j<=m;j++) ans=max(ans,dp[n+1][j]); printf("%d\n",ans); } int main() { while(~scanf("%d %d %d %d",&n,&m,&x,&t)) { init(); DP(); } return 0; }
不是一次过的,第一次提交之后跑了218ms wa掉了,感觉自己想的挺对的,后来找了下发现sum数组初始化的时候有点问题,后来又用for循环初始化了一下数组。结果就ac了,出乎我意料。感觉需要优化的dp,他的方程都不是特别难想?不清楚了,继续ac!五一节快乐!!