bzoj1814: Ural 1519 Formula 1 动态规划 插头dp
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1814: Ural 1519 Formula 1 动态规划 插头dp相关的知识,希望对你有一定的参考价值。
dbzoj依然爆炸
题目描述
一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数。
输入
The first line contains the integer numbers N and M (2 ≤ N, M ≤ 12). Each of the next N lines contains M characters, which are the corresponding cells of the rectangle. Character "." (full stop) means a cell, where a segment of the race circuit should be built, and character "*" (asterisk) - a cell, where a gopher hole is located.
输出
You should output the desired number of ways. It is guaranteed, that it does not exceed 2^63-1.
样例输入
4 4
**..
....
....
....样例输出
2
dfs时间复杂度才能通过,我直接写了个dp里面有很多无用状态,改成dfs的就行了。。不想改了就先这样吧。
匹配就行了……没什么技术含量。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<map> 7 using namespace std; 8 #define LL long long 9 int n,m; 10 char ch[15][15]={}; 11 int id[15][15]={}; 12 LL shu[15]={}; 13 map< int,LL >f[200]; 14 inline int getit(int z,int i){return (z/shu[i])%3;} 15 int main(){ 16 scanf("%d%d",&n,&m); 17 for(int i=1;i<=n;i++)scanf("%s",ch[i]+1); 18 for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)id[i][j]=(i-1)*m+j; 19 shu[1]=1;int ff=0; 20 for(int i=2;i<=m+1;i++)shu[i]=shu[i-1]*3; 21 if(ch[1][1]==‘.‘){f[1][1+2*3]=1;ff=1;} 22 else f[1][0]=1; 23 int mx=shu[m+1]*3,now,nex,fla,z,x,y; LL val; 24 for(int i=1;i<=n;i++){ 25 for(int j=1;j<m;j++){ 26 if(i==n&&j==m-1)break; 27 now=id[i][j];nex=now+1;fla=0; 28 if(ch[i][j+1]!=‘.‘)fla=1; 29 if(ch[i][j]==1)ff=1; 30 for(int w=ff;w<mx;w++){ 31 val=f[now][w]; 32 if(val==0)continue; 33 x=getit(w,j+1);y=getit(w,j+2); 34 if(fla){ 35 if(x==0&&y==0){ 36 z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2]; 37 f[nex][z]+=val; 38 } 39 continue; 40 } 41 if(x==0&&y==0){ 42 z=w+(1-x)*shu[j+1]+(2-y)*shu[j+2]; 43 f[nex][z]+=val; 44 } 45 else if(x==0||y==0){ 46 z=w+(x+y-x)*shu[j+1]+(0-y)*shu[j+2]; 47 f[nex][z]+=val; 48 z=w+(0-x)*shu[j+1]+(x+y-y)*shu[j+2]; 49 f[nex][z]+=val; 50 } 51 else if(x==y){ 52 z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2]; 53 int zz,zzz; 54 if(x==1){ 55 zz=-1;zzz=j+2; 56 while(zz!=0){ 57 ++zzz; 58 if(zzz>m+1)break; 59 if(getit(w,zzz)==1)--zz; 60 if(getit(w,zzz)==2) ++zz; 61 } 62 if(zz!=0)continue; 63 z=z+(1-2)*shu[zzz]; 64 } 65 else{ 66 zz=1;zzz=j+1; 67 while(zz!=0){ 68 --zzz; 69 if(zzz>m+1)break; 70 if(getit(w,zzz)==1)--zz; 71 if(getit(w,zzz)==2) ++zz; 72 } 73 if(zz!=0)continue; 74 z=z+(2-1)*shu[zzz]; 75 } 76 f[nex][z]+=val; 77 } 78 else if(x==2&&y==1){ 79 z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2]; 80 f[nex][z]+=val; 81 } 82 } 83 } 84 if(i==n)break; 85 now=i*m;nex=now+1; 86 fla=0; 87 if(ch[i+1][1]!=‘.‘)fla=1; 88 if(ch[i][m]==‘.‘)ff=1; 89 for(int w=ff;w<mx;++w){ 90 val=f[now][w]; 91 if(val==0)continue; 92 if(getit(w,m+1)!=0)continue; 93 x=getit(w,1); 94 if(fla){ 95 if(!x){ 96 z=(w%shu[m+1]-x)*3; f[nex][z]+=val; 97 } 98 continue; 99 } 100 if(x==1){ 101 z=(w%shu[m+1]-x)*3; 102 z=z+1;f[nex][z]+=val; 103 z=z+2;f[nex][z]+=val; 104 } 105 else if(x==0){ 106 z=(w%shu[m+1]-x)*3+1+2*3; 107 f[nex][z]+=val; 108 } 109 } 110 } 111 printf("%lld\n",f[n*m-1][shu[m]*1+shu[m+1]*2]); 112 return 0; 113 }
以上是关于bzoj1814: Ural 1519 Formula 1 动态规划 插头dp的主要内容,如果未能解决你的问题,请参考以下文章
bzoj1814Ural 1519 Formula 1 插头dp
bzoj1814: Ural 1519 Formula 1 动态规划 插头dp
bzoj 1814: Ural 1519 Formula 1 插头dp经典题