bzoj 1187 [HNOI2007]神奇游乐园

来源:互联网 发布:c语言奇数阶幻方 编辑:程序博客网 时间:2024/04/30 00:20

插头dp;参考cdq的论文;
感觉模仿po姐先把状态转移写出来,会更加清晰好调;
注意情况分类,与换行时的小讨论;

/**************************************************************    Problem: 1187    User: jiazihankk    Language: C++    Result: Accepted    Time:56 ms    Memory:2976 kb****************************************************************/#include<bits/stdc++.h>#define rep(i,k,n) for(int i=k;i<=(n);i++)#define rep2(i,k,n) for(int i=k;i>=(n);i--)#define inf 0x7f7f7f7f using namespace std;const int N=30000;int A[105][10],g[N],ans[N],Ans=-inf,n,m,S,state[N],tot=0;vector<pair<int,bool> > trans[7][1<<14];inline int press(int b[]){    int ret=0;rep(i,0,m)ret|=b[i]<<(2*i);return ret;}inline void antipress(int x){    static int a[10];    rep(i,0,m)a[i]=(x>>(i*2))&3;    rep(i,0,m)printf("%d ",a[i]);}void Cal(int x){    static int a[10],b[10],sta[10],p[10];    int top=0;    rep(i,0,m)a[i]=(x>>(i*2))&3;    rep(i,0,m){        if(a[i]==3)return;        if(!a[i])continue;        if(a[i]==1)sta[++top]=i;        else{if(!top)return;        p[sta[top]]=i;p[i]=sta[top];        sta[top--]=0;        }    }    if(top)return;    state[++tot]=x;    rep(i,1,m){        switch(a[i-1]<<2|a[i]){            case 0<<2|0:{                memcpy(b,a,sizeof(a));                trans[i][x].push_back(pair<int,bool>(press(b),false));                b[i-1]=1;b[i]=2;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;                }            case 1<<2|0:{                memcpy(b,a,sizeof(a));                trans[i][x].push_back(pair<int,bool>(press(b),true));                b[i-1]=0;b[i]=1;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 0<<2|1:{                memcpy(b,a,sizeof(a));                trans[i][x].push_back(pair<int,bool>(press(b),true));                b[i-1]=1;b[i]=0;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 1<<2|1:{                memcpy(b,a,sizeof(a));                b[i-1]=0,b[i]=0,b[p[i]]=1;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 2<<2|2:{                memcpy(b,a,sizeof(a));                b[i-1]=0,b[i]=0,b[p[i-1]]=2;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 2<<2|1:{                memcpy(b,a,sizeof(a));                b[i-1]=0;b[i]=0;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 1<<2|2:{                memcpy(b,a,sizeof(a));                b[i-1]=b[i]=0;                if(press(b)==0)                trans[i][x].push_back(pair<int,bool>(-1,true));                break;            }            case 0<<2|2:{                memcpy(b,a,sizeof(a));                trans[i][x].push_back(pair<int,bool>(press(b),true));                b[i-1]=2;b[i]=0;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }            case 2<<2|0:{                memcpy(b,a,sizeof(a));                trans[i][x].push_back(pair<int,bool>(press(b),true));                b[i-1]=0;b[i]=2;                trans[i][x].push_back(pair<int,bool>(press(b),true));                break;            }        }    }}  //left to down up to leftint main(){//freopen("in.in","r",stdin);//freopen("out.out","w",stdout);vector<pair<int,bool> > :: iterator it;    scanf("%d%d",&n,&m);    S=1<<((m+1)*2);    rep(i,0,S-1)     Cal(i); // rep(i,1,tot)antipress(state[i]);    rep(i,1,n)rep(j,1,m)    scanf("%d",&A[i][j]);     memset(ans,-0x7f,sizeof(ans));    memset(g,-0x7f,sizeof(g));    ans[0]=0;/*      rep(j,1,m){        printf("%d\n",j);    rep(k,1,tot){    int tmp=state[k];    for(it=trans[j][tmp].begin();it!=trans[j][tmp].end();++it){        antipress(tmp);printf("--->");if(it->first==-1)printf("Ans");else antipress(it->first);        printf("\n");    }}}*/rep(i,1,n){    rep(j,1,m){        rep(k,1,tot)        if(ans[state[k]]>-inf)        {int tmp=state[k];            for(it=trans[j][tmp].begin();it!=trans[j][tmp].end();it++){                int ccc=it->first;                int& val=it->first!=-1 ? g[it->first] : Ans;                int cc=ans[tmp]+(it->second ? 1 : 0)*A[i][j];                val=max(val,cc);            }           }        if(j!=m)rep(k,1,tot)ans[state[k]]=g[state[k]];        else {rep(k,1,tot)ans[state[k]]=-inf;    //        rep(k,1,tot)if(!(state[k]>>(2*m)))ans[state[k]<<2]=g[state[k]];   //        }        rep(k,1,tot)g[state[k]]=-inf;    }}    printf("%d",Ans);        return 0;}

A掉也是有些激动呢T^T

0 0
原创粉丝点击