[BZOJ1187][HNOI2007]神奇游乐园

来源:互联网 发布:java面试速成 编辑:程序博客网 时间:2024/04/29 19:14

原题地址

插头DP.细节很多.

AC code:

#include <cstdio>#include <queue>#include <map>#include <algorithm>using namespace std;const int N=101;const int M=11;int n,m,ans=-(1<<28);int bt[M];int w[N][M];map<int,int> f[N][M];map<int,bool> vis[N][M];struct State{    int i,j,S;    State(int i,int j,int S):i(i),j(j),S(S) {}};void read(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++)            scanf("%d",&w[i][j]);    }    for(int i=1;i<=m+1;i++) bt[i]=(m-i+1)<<1;}int get(int S,int k){    return ((S&(1<<bt[k]))+(S&(1<<(bt[k]+1))))>>bt[k];}int modify(int S,int k,int s){    return S^(get(S,k)<<bt[k])^(s<<bt[k]);}void BFS(){    queue<State> Q;    Q.push(State(0,m,0));    while(!Q.empty()){        State x=Q.front();        Q.pop();        int i=x.i,j=x.j+1,S=x.S;        if(j==m+1){            i++;j=1;            S>>=2;            if(i==n+1) break;        }        int c1=get(S,j),c2=get(S,j+1);        if((!c1)&&(!c2)){            if(!vis[i][j][S]){                vis[i][j][S]=1;                Q.push(State(i,j,S));                f[i][j][S]=f[x.i][x.j][x.S];            }            else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]);        }        if(c1&&(!c2)&&i!=n){            if(!vis[i][j][S]){                vis[i][j][S]=1;                Q.push(State(i,j,S));                f[i][j][S]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]+w[i][j]);        }        if((!c1)&&c2&&j!=m){            if(!vis[i][j][S]){                vis[i][j][S]=1;                Q.push(State(i,j,S));                f[i][j][S]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][S]=max(f[i][j][S],f[x.i][x.j][x.S]+w[i][j]);        }        if((!c1)&&c2&&i!=n){            int SS=modify(modify(S,j,c2),j+1,c1);            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if(c1&&(!c2)&&j!=m){            int SS=modify(modify(S,j,c2),j+1,c1);            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if((!c1)&&(!c2)&&i!=n&&j!=m){            int SS=modify(modify(S,j,1),j+1,2);            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if(c1==2&&c2==1){            int SS=modify(modify(S,j,0),j+1,0);            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if(c1==1&&c2==1){            int cnt=0,SS=modify(modify(S,j,0),j+1,0);            for(int k=j+2;k<=m+1;k++){                if(get(SS,k)==2) cnt++;                else if(get(SS,k)==1) cnt--;                if(cnt==1){                    SS=modify(SS,k,1);                    break;                }            }            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if(c1==2&&c2==2){            int cnt=0,SS=modify(modify(S,j,0),j+1,0);            for(int k=j-1;k>=1;k--){                if(get(SS,k)==1) cnt++;                else if(get(SS,k)==2) cnt--;                if(cnt==1){                    SS=modify(SS,k,2);                    break;                }            }            if(!vis[i][j][SS]){                vis[i][j][SS]=1;                Q.push(State(i,j,SS));                f[i][j][SS]=f[x.i][x.j][x.S]+w[i][j];            }            else f[i][j][SS]=max(f[i][j][SS],f[x.i][x.j][x.S]+w[i][j]);        }        if(c1==1&&c2==2){            int cnt=0;            for(int k=1;k<=m+1;k++){                if(get(S,k)==1) cnt++;            }            if(cnt==1) ans=max(ans,f[x.i][x.j][x.S]+w[i][j]);        }    }    printf("%d",ans);}int main(){    read();    BFS();    return 0;}
0 0
原创粉丝点击