辣鸡题目,毁我青春,费我时间,害我性命。
白书上的题目,轮廓线状压DP真是无爱了。
思考半小时,代码两小时TAT,我又回忆起了NOIP上写的那个脑残状压DP了,坑爹的优化。。。。。。
不过好歹1A了是不是。
这波不亏
手算一下有11种转移。
都列出来然后就是码码码了。
MD有个转移算错了查了半小时,还顺便学了下GDB
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=(1<<20)+5; const int inf=1e9; int f[2][N],table[N],tot,bin[30],n,m; int get(int pos,int x){ switch(x){ case 0:return 0; case 1:return bin[2*pos-1]; case 2:return bin[pos<<1]; } } int state(int pos,int s){ if(s&bin[pos<<1])return 2; else if(s&bin[2*pos-1])return 1; return 0; } void print(int s){ for(int i=1;i<=m+1;i++) printf("%d",state(i,s)); putchar('\n'); } void dfs(int pos,int s){ if(pos>m+1){ table[++tot]=s; return; } for(int i=0;i<3;i++) dfs(pos+1,s|get(pos,i)); } #define relax(x) (x=min(x,f[last][s])) #define update(x) (x=min(x,f[last][s]+1)) #define update1(x) (x=min(x,f[last][s]+2)) int main(){ //freopen("a.in","r",stdin); bin[1]=1; for(int i=2;i<=25;i++)bin[i]=bin[i-1]<<1; while(scanf("%d%d",&n,&m)&&n){ int flag,x,y,all=bin[2*m+3]-1; int now=0,last=1; tot=0; dfs(1,0); for(int i=1;i<=tot;i++)f[now][table[i]]=inf; f[now][0]=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&flag); flag--; now^=1;last^=1; for(int k=1;k<=tot;k++)f[now][table[k]]=inf; for(int k=1;k<=tot;k++){ int s=table[k]; x=state(m+1,s);y=state(m,s); if(!flag){ if(!x&&!y)relax(f[now][s<<2]); }else if(flag>0){ if(!x&&!y){ if(j!=m)update(f[now][(s<<2)|get(m+1,flag)]); if(i!=n)update(f[now][(s<<2)|get(1,flag)]); }else if(!x&&y==flag){ if(i!=1)relax(f[now][(s<<2)&all^get(m+1,flag)]); }else if(x==flag&&!y){ if(j!=1)relax(f[now][(s<<2)&all]); } }else{ if(!x){ if(!y){ relax(f[now][s<<2]); if(j!=m&&i!=n){ update1(f[now][(s<<2)|get(1,1)|get(m+1,1)]); update1(f[now][(s<<2)|get(1,2)|get(m+1,2)]); } }else{ if(j!=m)update(f[now][s<<2]); if(i!=n)update(f[now][(s<<2)^get(m+1,y)|get(1,y)]); } }else{ if(!y){ if(j!=m)update(f[now][(s<<2)&all|get(m+1,x)]); if(i!=n)update(f[now][(s<<2)&all|get(1,x)]); }else{ if(x==y)relax(f[now][(s<<2)&all^get(m+1,x)]); } } } }/* printf("%d %d\n",i,j); for(int k=1;k<=tot;k++) if(f[now][table[k]]!=inf){ print(table[k]); printf("%d\n",f[now][table[k]]); }*/ } int ans=inf; ans=f[now][0]; if(ans==inf)ans=0; printf("%d\n",ans); } return 0; }