zoukankan      html  css  js  c++  java
  • bzoj1814: Ural 1519 Formula 1 动态规划 插头dp

    http://acm.timus.ru/problem.aspx?space=1&num=1519

    题目描述

    一个 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

     

    直接写时间复杂度过不了,直接写了个dp里面有很多无用状态,剪枝一下(存下一个的有用状态)就行了。

      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
    ",f[n*m-1][shu[m]*1+shu[m+1]*2]);
    112     return 0;
    113 }
    原代码

    更改之后不开O2跑12*12的无障碍图需要快2s,大概是用map复杂度加了个log的锅……不想写hash……

      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 int cun[2][400010]={},tot[2]={};
     13 LL shu[15]={};
     14 map< int,LL >f[200];
     15 inline int getit(int z,int i){return (z/shu[i])%3;}
     16 int main(){
     17     scanf("%d%d",&n,&m);
     18     for(int i=1;i<=n;i++)scanf("%s",ch[i]+1);
     19     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)id[i][j]=(i-1)*m+j;
     20     shu[1]=1;
     21     for(int i=2;i<=m+1;i++)shu[i]=shu[i-1]*3;
     22     if(ch[1][1]=='.'){f[1][1+2*3]=1;tot[1]=1;cun[1][1]=1+2*3;}
     23     else { f[1][0]=1;tot[1]=1;cun[1][1]=0;}
     24     int now,nex,fla,z,x,y,id1,id2; LL val;
     25     for(int i=1;i<=n;i++){
     26         for(int j=1;j<m;j++){
     27             if(i==n&&j==m-1)break;
     28             now=id[i][j];nex=now+1;fla=0;
     29             if(ch[i][j+1]!='.')fla=1;
     30             id1=id[i][j]&1;id2=id1^1;
     31             tot[id2]=0;
     32             for(int k=1;k<=tot[id1];k++){
     33                 int w=cun[id1][k];
     34                 val=f[now][w];
     35                 if(val==0)continue;
     36                 x=getit(w,j+1);y=getit(w,j+2);
     37                 if(fla){
     38                     if(x==0&&y==0){
     39                         z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     40                         if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     41                         f[nex][z]+=val;
     42                     }
     43                     continue;
     44                 }
     45                 if(x==0&&y==0){
     46                     z=w+(1-x)*shu[j+1]+(2-y)*shu[j+2];
     47                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     48                     f[nex][z]+=val;
     49                 }
     50                 else if(x==0||y==0){
     51                     z=w+(x+y-x)*shu[j+1]+(0-y)*shu[j+2];
     52                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     53                     f[nex][z]+=val;
     54                     z=w+(0-x)*shu[j+1]+(x+y-y)*shu[j+2];
     55                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     56                     f[nex][z]+=val;
     57                 }
     58                 else if(x==y){
     59                     z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     60                     int zz,zzz;
     61                     if(x==1){
     62                         zz=-1;zzz=j+2;
     63                         while(zz!=0){
     64                             ++zzz;
     65                             if(zzz>m+1)break;
     66                             if(getit(w,zzz)==1)--zz;
     67                             if(getit(w,zzz)==2) ++zz;
     68                         }
     69                         if(zz!=0)continue;
     70                         z=z+(1-2)*shu[zzz];
     71                     }
     72                     else{
     73                         zz=1;zzz=j+1;
     74                         while(zz!=0){
     75                             --zzz;
     76                             if(zzz>m+1)break;
     77                             if(getit(w,zzz)==1)--zz;
     78                             if(getit(w,zzz)==2) ++zz;
     79                         }
     80                         if(zz!=0)continue;
     81                         z=z+(2-1)*shu[zzz];
     82                     }
     83                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     84                     f[nex][z]+=val;
     85                 }
     86                 else if(x==2&&y==1){
     87                     z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     88                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     89                     f[nex][z]+=val;
     90                 }
     91             }
     92         }
     93         if(i==n)break;
     94         now=i*m;nex=now+1;
     95         fla=0;
     96         if(ch[i+1][1]!='.')fla=1;
     97         id1=id[i][m]&1;id2=id1^1;
     98         tot[id2]=0;
     99         for(int k=1;k<=tot[id1];++k){
    100             int w=cun[id1][k];
    101             val=f[now][w];
    102             if(val==0)continue;
    103             if(getit(w,m+1)!=0)continue;
    104             x=getit(w,1);
    105             if(fla){
    106                 if(!x){
    107                     z=(w%shu[m+1]-x)*3;
    108                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    109                     f[nex][z]+=val;
    110                 }
    111                 continue;
    112             }
    113             if(x==1){
    114                 z=(w%shu[m+1]-x)*3;
    115                 z=z+1; if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    116                 f[nex][z]+=val;
    117                 z=z+2; if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    118                 f[nex][z]+=val;
    119             }
    120             else if(x==0){
    121                 z=(w%shu[m+1]-x)*3+1+2*3;
    122                 if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    123                 f[nex][z]+=val;
    124             }
    125         }
    126     }
    127     printf("%lld
    ",f[n*m-1][shu[m]*1+shu[m+1]*2]);
    128     return 0;
    129 }
    去掉无用状态后

    用map竟然过了……不过要注意一下最后输出的是最后一个可行位置的答案,很有可能最后一个点不是可行的,被坑了一下QAQ

      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 int cun[2][400010]={},tot[2]={};
     13 LL shu[15]={};
     14 map< int,LL >f[200];
     15 inline int getit(int z,int i){return (z/shu[i])%3;}
     16 int main(){
     17     scanf("%d%d",&n,&m);
     18     for(int i=1;i<=n;i++)scanf("%s",ch[i]+1);
     19     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)id[i][j]=(i-1)*m+j;
     20     int idx=0,idy=0;
     21     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(ch[i][j]=='.'){idx=i;idy=j;}
     22     if(idy<=1){printf("0
    ");return 0;}
     23     shu[1]=1;
     24     for(int i=2;i<=m+1;i++)shu[i]=shu[i-1]*3;
     25     if(ch[1][1]=='.'){f[1][1+2*3]=1;tot[1]=1;cun[1][1]=1+2*3;}
     26     else { f[1][0]=1;tot[1]=1;cun[1][1]=0;}
     27     int now,nex,fla,z,x,y,id1,id2; LL val;
     28     for(int i=1;i<=idx;i++){
     29         for(int j=1;j<m;j++){
     30             if(i==n&&j==m-1)break;
     31             now=id[i][j];nex=now+1;fla=0;
     32             if(ch[i][j+1]!='.')fla=1;
     33             id1=id[i][j]&1;id2=id1^1;
     34             tot[id2]=0;
     35             for(int k=1;k<=tot[id1];k++){
     36                 int w=cun[id1][k];
     37                 val=f[now][w];
     38                 if(val==0)continue;
     39                 x=getit(w,j+1);y=getit(w,j+2);
     40                 if(fla){
     41                     if(x==0&&y==0){
     42                         z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     43                         if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     44                         f[nex][z]+=val;
     45                     }
     46                     continue;
     47                 }
     48                 if(x==0&&y==0){
     49                     z=w+(1-x)*shu[j+1]+(2-y)*shu[j+2];
     50                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     51                     f[nex][z]+=val;
     52                 }
     53                 else if(x==0||y==0){
     54                     z=w+(x+y-x)*shu[j+1]+(0-y)*shu[j+2];
     55                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     56                     f[nex][z]+=val;
     57                     z=w+(0-x)*shu[j+1]+(x+y-y)*shu[j+2];
     58                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     59                     f[nex][z]+=val;
     60                 }
     61                 else if(x==y){
     62                     z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     63                     int zz,zzz;
     64                     if(x==1){
     65                         zz=-1;zzz=j+2;
     66                         while(zz!=0){
     67                             ++zzz;
     68                             if(zzz>m+1)break;
     69                             if(getit(w,zzz)==1)--zz;
     70                             if(getit(w,zzz)==2) ++zz;
     71                         }
     72                         if(zz!=0)continue;
     73                         z=z+(1-2)*shu[zzz];
     74                     }
     75                     else{
     76                         zz=1;zzz=j+1;
     77                         while(zz!=0){
     78                             --zzz;
     79                             if(zzz>m+1)break;
     80                             if(getit(w,zzz)==1)--zz;
     81                             if(getit(w,zzz)==2) ++zz;
     82                         }
     83                         if(zz!=0)continue;
     84                         z=z+(2-1)*shu[zzz];
     85                     }
     86                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     87                     f[nex][z]+=val;
     88                 }
     89                 else if(x==2&&y==1){
     90                     z=w+(0-x)*shu[j+1]+(0-y)*shu[j+2];
     91                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
     92                     f[nex][z]+=val;
     93                 }
     94             }
     95         }
     96         if(i==n)break;
     97         now=i*m;nex=now+1;
     98         fla=0;
     99         if(ch[i+1][1]!='.')fla=1;
    100         id1=id[i][m]&1;id2=id1^1;
    101         tot[id2]=0;
    102         for(int k=1;k<=tot[id1];++k){
    103             int w=cun[id1][k];
    104             val=f[now][w];
    105             if(val==0)continue;
    106             if(getit(w,m+1)!=0)continue;
    107             x=getit(w,1);
    108             if(fla){
    109                 if(!x){
    110                     z=(w%shu[m+1]-x)*3;
    111                     if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    112                     f[nex][z]+=val;
    113                 }
    114                 continue;
    115             }
    116             if(x==1){
    117                 z=(w%shu[m+1]-x)*3;
    118                 z=z+1; if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    119                 f[nex][z]+=val;
    120                 z=z+2; if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    121                 f[nex][z]+=val;
    122             }
    123             else if(x==0){
    124                 z=(w%shu[m+1]-x)*3+1+2*3;
    125                 if(f[nex][z]==0)cun[id2][++tot[id2]]=z;
    126                 f[nex][z]+=val;
    127             }
    128         }
    129     }
    130     printf("%lld
    ",f[(idx-1)*m+idy-1][shu[idy]*1+shu[idy+1]*2]);
    131     return 0;
    132 }
    这绝对是最后一版了

    cnblog什么毛病啊……给代码加了标题如果要复制代码标题就到代码末尾了……mdzz

  • 相关阅读:
    字符串打印
    倒计时(二)之时间戳
    倒计时(一)之数字补0
    递增、递减运算符
    如何让background里的img图片自适应
    CSS三角图标(二)
    CSS三角图标(一)
    网易云外链接生成方法
    python基础语法一
    CSS固定菜单栏
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8994374.html
Copyright © 2011-2022 走看看