您的位置:首页 > 其它

POJ 3133 Manhattan Wiring

2016-02-27 12:00 281 查看
辣鸡题目,毁我青春,费我时间,害我性命。

白书上的题目,轮廓线状压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]
,table
,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: