[BZOJ 1499] 瑰丽华尔兹

Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1499

 

Solution :

能立即发现这是和动态规划相关的题目

 

令f[t][i][j]表示第t段时间时,钢琴位于(i,j)处时,从第1段时间到第t段时间的最长滑行路程。

f[t][i][j]=max{ f[t−1][i last][j last] + dist{ (i last,j last) , (i,j) } }

 

由于四个方向的处理类似,这里以向右举例:

f[t][i][j]=max{ f[t−1][i][j′] + (j−j′) }=j+max{f[t−1][i][j′]−j′} , j−j′≤end-start+1

 

对于每个f[t][i][j],我们就是找到最大的max{f[t−1][i][j′]−j′},同时使得j−j′≤end-start+1

由于j-j'单调递减,每次需要弹出队首元素,我们使用单调队列而非单调栈来维护这个序列

 
Code:
#include <bits/stdc++.h>

using namespace std;
const int MAXN=300;
const int INF=1<<27;

inline int read()
{
    char ch;int num,f=0;
    while(!isdigit(ch=getchar())) f|=(ch=='-');
    num=ch-'0';
    while(isdigit(ch=getchar())) num=num*10+ch-'0';
    return f?-num:num;
}

int n,m,X,Y,k,dp[2][MAXN][MAXN],d=0;  //滚动数组优化
char dat[MAXN][MAXN];

int st,end,dir,res=0,que[MAXN],t[MAXN];
int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1};

void solve(int x,int y)
{
    int l=1,r=0,now=1;
    while(x>=1 && x<=n && y>=1 && y<=m)
    {
        if(dat[x][y]=='x') l=1,r=0;
        while(l<=r && now-t[l]>end-st+1) l++;  //弹出队首
        while(l<=r && que[r]<dp[d^1][x][y]-now) r--;  //保证递减的单调性
        que[++r]=dp[d^1][x][y]-now;t[r]=now;
        dp[d][x][y]=que[l]+now;
        
        res=max(res,dp[d][x][y]);now++;
        x+=dx[dir];y+=dy[dir];
    }
}

int main()
{
    cin >> n >> m >> X >> Y >> k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin >> dat[i][j];
    memset(dp,0x80,sizeof(dp));
    
    dp[0][X][Y]=0;
    for(int i=1;i<=k;i++)
    {
        st=read(),end=read(),dir=read();
        d^=1;
        if(dir==1)
            for(int i=1;i<=m;i++) solve(n,i);
        else if(dir==2)
            for(int i=1;i<=m;i++) solve(1,i);
        else if(dir==3)
            for(int i=1;i<=n;i++) solve(i,m);
        else 
            for(int i=1;i<=n;i++) solve(i,1);
    }
    cout << res;
    return 0;
}

 

Review:
1、对于有决策单调性的DP,
考虑利用其单调性优化(斜率优化,单调栈,单调队列
 
同时注意考虑限制条件,判断何时弹出队首
 
2、如果DP的数组每一层只用一次,使用滚动数组优化空间
posted @ 2018-05-24 15:40  NewErA  阅读(253)  评论(0编辑  收藏  举报