您的位置:首页 > 其它

hdu 4374 我的第一道单调队列优化的DP

2013-05-01 14:59 429 查看
  只贴代码:  

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!五一节快乐!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: