其他分享
首页 > 其他分享> > 洛谷 - P3786 - 萃香抱西瓜 - 状压dp

洛谷 - P3786 - 萃香抱西瓜 - 状压dp

作者:互联网

重构一下就过了,不知道之前错在哪里。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;

const int INF=0x3f3f3f3f;

int solve();

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
#endif // Yinku
    solve();
}

int dp[6][6][101][1<<11];
//dp[w][h][t][ch] 表示t时间xy处的接到西瓜状态为ch的最小步数

int g[6][6][101];
//g[w][h][t] 表示t时间xy处的西瓜有哪些

int h,w;

inline void update(int x,int y,int t,int ost,int nst) {
    if(g[x][y][t+1]&(1<<0))
        return;
    if(x>1)
        dp[x][y][t+1][nst]=min(dp[x][y][t+1][nst],dp[x-1][y][t][ost]+1);
    if(x<w)
        dp[x][y][t+1][nst]=min(dp[x][y][t+1][nst],dp[x+1][y][t][ost]+1);
    if(y>1)
        dp[x][y][t+1][nst]=min(dp[x][y][t+1][nst],dp[x][y-1][t][ost]+1);
    if(y<h)
        dp[x][y][t+1][nst]=min(dp[x][y][t+1][nst],dp[x][y+1][t][ost]+1);
    return;
}

int solve() {
    int T,sx,sy;
    scanf("%d%d%d%d%d",&h,&w,&T,&sx,&sy);
    int n,m;
    scanf("%d%d",&n,&m);

    memset(g,0,sizeof(g));

    int id=1;
    for(int i=1; i<=n; i++) {
        int t1,t2,a;
        scanf("%d%d%d",&t1,&t2,&a);
        for(int t=t1; t<t2; t++) {
            int x,y;
            scanf("%d%d",&x,&y);
            if(a==1) {
                g[x][y][t]|=(1<<id);
            } else {
                g[x][y][t]|=(1<<0);
            }
        }
        if(a==1)
            id++;
    }



    /*for(int t=1; t<=T; t++) {
        for(int nx=1; nx<=w; nx++) {
            for(int ny=1; ny<=h; ny++) {
                cout<<bitset<4>(g[nx][ny][t])<<" ";
            }
            cout<<endl;
        }
        cout<<endl;
    }*/

    if(g[sx][sy][1]&(1<<0)) {
        printf("-1\n");
        return 0;
    }

    memset(dp,INF,sizeof(dp));
    int ch=g[sx][sy][1];

    dp[sx][sy][1][ch]=0;

    for(int t=1; t<T; t++) {
        for(int nx=1; nx<=w; nx++) {
            for(int ny=1; ny<=h; ny++) {
                int nch=g[nx][ny][t+1];
                if(nch&(1<<0))
                    continue;
                for(int ch=0; ch<(1<<id); ch++) {
                    dp[nx][ny][t+1][ch]=min(dp[nx][ny][t+1][ch],dp[nx][ny][t][ch]);
                }
            }
        }
        for(int nx=1; nx<=w; nx++) {
            for(int ny=1; ny<=h; ny++) {
                int nch=g[nx][ny][t+1];
                if(nch&(1<<0))
                    continue;
                for(int ch=0; ch<(1<<id); ch++) {
                    update(nx,ny,t,ch,ch|nch);
                }
            }
        }
    }

    /*for(int t=1; t<=T; t++) {
        printf("t=%d\n",t);

        for(int i=0; i<((1<<id)-1); i++) {
            cout<<"i="<<bitset<10>(i)<<endl;
            for(int nx=1; nx<=w; nx++) {
                for(int ny=1; ny<=h; ny++) {
                    printf("%2d ",dp[nx][ny][t][i]!=INF?dp[nx][ny][t][i]:-1);
                }
                printf("\n");
            }
            cout<<endl;
        }
        printf("\n");
    }*/

    int ans=INF;
    for(int nx=1; nx<=w; nx++) {
        for(int ny=1; ny<=h; ny++) {
            if(g[nx][ny][T]&(1<<0))
                continue;
            else {
                ans=min(ans,dp[nx][ny][T][(1<<id)-2]);
            }
        }
    }

    if(ans==INF)
        ans=-1;
    printf("%d\n",ans);

    return 0;
}

标签:洛谷,min,int,Yinku,状压,ost,萃香,nst,dp
来源: https://www.cnblogs.com/Yinku/p/10940789.html