zoukankan      html  css  js  c++  java
  • ZOJ 3466 The Hive II

      插头DP。。

      求用若干个回路走遍整张图的方案数。。然而格子是六边形的TAT

      想了好久...按照列来转移好写一点。。其实和正方形格子差不多?

      膜了标程才知道,如果回路数没有限制的话。。可以只记录有没有插头,而不用去记录插头属于哪个联通块。。

      (要是去记录插头属于哪个联通块就会爆long long了TAT

      代码依然很慢。。。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxzt=1023333,modd=6023,inf=1002333333;
      8 struct zs1{
      9     struct zs{
     10         int too,pre;
     11     }e[maxzt];int tot,last[modd];
     12     int zt[maxzt];
     13     ll f[maxzt];
     14     inline int get(int v){
     15         int i,x=v%modd;
     16         for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
     17         if(i)return i;
     18         e[++tot].too=v,e[tot].pre=last[x],last[x]=tot;
     19         f[tot]=0,zt[tot]=v;
     20         return tot;
     21     }
     22 }hm[2];
     23 bool can[13][13];
     24 int mp[21];
     25 int i,j,k,n,m,ans;
     26 
     27 inline void upd(int &a,int b){if(b<a)a=b;}
     28 
     29 inline int encode(){
     30     int x=0;
     31     for(int i=0;i<n<<1;i++)x=x<<1|mp[i];return x;
     32 }
     33 inline void decode(int x){
     34     for(int i=n*2-1;i>=0;i--)mp[i]=x&1,x>>=1;
     35 }
     36 inline void clr(bool now){
     37     memset(hm[now].last,0,modd<<2);
     38     hm[now].tot=0;
     39 }
     40 inline void dp_blank(int x,int y,bool pre){
     41     int up,zx,zs,i,zt;ll f;bool now=pre^1;int posup,poszs,poszx,ys,yx;
     42     if(y&1)ys=x;else ys=x-1;yx=ys+1;
     43     clr(now);//printf("    %d,%d
    ",x,y);
     44     for(i=1;i<=hm[pre].tot;i++){
     45         zt=hm[pre].zt[i],f=hm[pre].f[i];
     46         if(x==1)zt>>=1;
     47         decode(zt);
     48 //        for(int j=0;j<n<<1;j++)printf(" %d",mp[j]);printf("   %lld
    ",f);
     49         if(y&1)posup=(x<<1)-2,poszs=(x<<1)-1,poszx=x<<1;
     50             else posup=max(0,(x<<1)-3),poszs=(x<<1)-2,poszx=(x<<1)-1;
     51         up=mp[posup],zs=mp[poszs],zx=mp[poszx];
     52 //        printf("   %d %d %d     %d %d %d
    ",up,zs,zx,posup,poszs,poszx);
     53         if(up+zs+zx==0){
     54             if(can[x+1][y]&&can[ys][y+1])
     55                 mp[poszs]=0,mp[poszx]=mp[posup]=1,
     56                 hm[now].f[ hm[now].get(encode()) ]+=f;
     57             if(can[x+1][y]&&can[yx][y+1])
     58                 mp[posup]=0,mp[poszx]=mp[poszs]=1,
     59                 hm[now].f[ hm[now].get(encode()) ]+=f;
     60             if(can[ys][y+1]&&can[yx][y+1])
     61                 mp[poszx]=0,mp[posup]=mp[poszs]=1,
     62                 hm[now].f[ hm[now].get(encode()) ]+=f;
     63         }
     64         if(up+zs+zx==1){
     65             if(can[x+1][y])
     66                 mp[poszs]=mp[posup]=0,mp[poszx]=1,
     67                 hm[now].f[ hm[now].get(encode()) ]+=f;
     68             if(can[ys][y+1])
     69                 mp[poszs]=mp[poszx]=0,mp[posup]=1,
     70                 hm[now].f[ hm[now].get(encode()) ]+=f;
     71             if(can[yx][y+1])//puts("yx"),
     72                 mp[posup]=mp[poszx]=0,mp[poszs]=1,
     73                 hm[now].f[ hm[now].get(encode()) ]+=f;
     74         }
     75         if(up+zs+zx==2)
     76             mp[poszx]=mp[poszs]=mp[posup]=0,
     77             hm[now].f[ hm[now].get(encode()) ]+=f;
     78     }
     79 }
     80 inline void dp_bar(int x,int y,bool pre){
     81     int i,up,zs,zx,zt;ll f;bool now=pre^1;int posup,poszs,poszx;
     82     
     83     clr(now);//printf("   # %d,%d
    ",x,y);
     84     for(i=1;i<=hm[pre].tot;i++){
     85         zt=hm[pre].zt[i],f=hm[pre].f[i];
     86         if(x==1)zt>>=1;
     87         decode(zt);
     88 //        for(int j=0;j<n<<1;j++)printf(" %d",mp[j]);printf("    %lld
    ",f);
     89         if(y&1)posup=(x<<1)-2,poszs=(x<<1)-1,poszx=x<<1;
     90             else posup=max(0,(x<<1)-3),poszs=(x<<1)-2,poszx=(x<<1)-1;
     91         up=mp[posup],zs=mp[poszs],zx=mp[poszx];
     92         if(up+zs+zx==0)
     93             hm[now].f[ hm[now].get(encode()) ]+=f;
     94     }
     95 }
     96 char s[23];
     97 int main(){
     98     while(scanf("%d",&n)!=EOF){
     99         scanf("%d",&m);
    100         memset(can,0,sizeof(can));
    101         for(i=1;i<=n;i++)for(j=1;j<=8;j++)can[i][j]=1;
    102         for(i=1;i<=m;i++)scanf("%s",s),can[s[0]-'A'+1][s[1]-'A'+1]=0;
    103         
    104         bool now=1,pre=0;
    105         clr(pre),hm[pre].f[ hm[pre].get(0) ]=1;
    106         for(j=1;j<=8;j++)for(i=1;i<=n;swap(now,pre),i++)
    107             if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
    108         ll ans=0;
    109         for(i=1;i<=hm[pre].tot;i++)ans+=hm[pre].f[i];
    110         printf("%lld
    ",ans);
    111     }
    112     return 0;
    113 }
    View Code

    发现取模的数字会对效率有很大影响。。。。平时似乎不会啊= =

    模数取10w出头就好了。。

  • 相关阅读:
    第12讲:数据库完整性
    第11讲:视图及其应用
    第10讲:利用SQL语言实现关系代数操作
    ArcEngine 坐标系转换
    [转]ArcGIS计算图斑的四邻坐标(XMin,XMax,YMin,YMax)
    oracle11g 修改字符集 修改为ZHS16GBK
    Oracle 全文索引相关命令
    SQL语句 递归
    流量操控之SSH隧道与端口转发
    VIM 常用操作
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5491324.html
Copyright © 2011-2022 走看看