[Section DP] ZOJ3541 The Last Puzzle

 

[Section DP] ZOJ3541 The Last Puzzle

Face questions

N you buttons, each button has a recovery time and location, can be moved per unit distance, such a solution is given all at one time button is depressed the whole

answer

First consider the feasibility

For easy discovery interval [L, R] is not the beginning by L is R 

Another dp [i] [j] [0] represents a [i, j] from the left by

dp [i] [j] [1] represents a press from the right

Obviously [i, j] may be transferred from the [i + 1, j] and [i, j-1]

When the transfer recording option left or right you can solve the output program

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 200 + 10;

inline int read()
{
    int f=1,x=0;
    char ch;
    do
    {
        ch=getchar();
        if(ch=='-') f=-1;
    }while(ch<'0'||ch>'9');
    do
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }while(ch>='0'&&ch<='9');
    return f*x;
}

int n;
int dp[MAXN][MAXN][2];
int d[MAXN];
int t[MAXN];
int next[MAXN][MAXN][2];

int main()
{
    while(~scanf("%d",&n))
    {
        for(register int i=1;i<=n;i++) t[i]=read();
        for(register int i=1;i<=n;i++) d[i]=read();
        memset(dp,0,sizeof(dp));
        for(register int len=2;len<=n;len++)
        {
            for(register int i=1;i+len-1<=n;i++)
            {
                int j=i+len-1;
                dp[i][j][0]=min(dp[i+1][j][0]+d[i+1]-d[i],dp[i+1][j][1]+d[j]-d[i]);
                next[i][j][0]=(dp[i+1][j][0]+d[i+1]-d[i]>dp[i+1][j][1]+d[j]-d[i]);
                if(dp[i][j][0]>=t[i]||dp[i][j][0]>=(1<<30)) dp[i][j][0]=1<<30;
                dp[i][j][1]=min(dp[i][j-1][0]+d[j]-d[i],dp[i][j-1][1]+d[j]-d[j-1]);
                next[i][j][1]=(dp[i][j-1][0]+d[j]-d[i]>dp[i][j-1][1]+d[j]-d[j-1]);
                if(dp[i][j][1]>=t[j]||dp[i][j][1]>=(1<<30)) dp[i][j][1]=1<<30;
            }
        }
        if(dp[1][n][0]<(1<<30))
        {
            printf("1");
            int l=2,r=n;
            int flag=next[1][n][0];
            while(l<=r)
            {
                if(!flag)
                {
                    printf(" %d",l);
                    flag=next[l][r][0];
                    l++;
                }
                else
                {
                    printf(" %d",r);
                    flag=next[l][r][1];
                    r--;
                }
            }
            cout<<endl;
        }
        else if(dp[1][n][1]<(1<<30))
        {
            printf("%d" ,n);
            int l=1,r=n-1;
            int flag=next[1][n][1];
            while(l<=r)
            {
                if(!flag)
                {
                    printf(" %d",l);
                    flag=next[l][r][0];
                    l++;
                }
                else
                {
                    printf(" %d",r);
                    flag=next[l][r][1];
                    r--;
                }
            }
            cout<<endl;
        }
        else cout<<"Mission Impossible"<<endl;
    }
}

 

Guess you like

Origin www.cnblogs.com/wlzs1432/p/11294111.html