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 }
View Code

 





以上是关于bzoj1814: Ural 1519 Formula 1 动态规划 插头dp的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1814Ural 1519 Formula 1 插头dp

bzoj1814: Ural 1519 Formula 1 动态规划 插头dp

bzoj 1814: Ural 1519 Formula 1 插头dp经典题

bzoj 1814: Ural 1519 Formula 1插头dp

插头dp题表(已完成)

[URAL1519]Formula 1