zoukankan      html  css  js  c++  java
  • Tour in the Castle(ZOJ3256 矩阵加速插头dp)

    传送门

    Tour in the Castle

    Time Limit: 5 Seconds      Memory Limit: 32768 KB

    After the final BOSS is defeated, the hero found that the whole castle is collapsing (very familiar scene, isn't it). Escape from the castle is easy, just need to cross a few rooms. But as the Hero is full of adventurous spirit, he decides to visit every room before he escape the castle.

    The castle is a rectangle with N * M rooms in it. Two rooms are connected if they share a common edge. The hero starts in the top left room. And the bottom left room is the only way out. After the hero visits a room and leaves it, it will collapse immediately(Another familiar scene). So he can visit each room only once.

    The diagram shows one tour over a castle with 4 * 10 rooms:

    Input

    There are multiply cases (<20), process to the end of file.

    Each case contains a line with two Integer N and M (2 <= N <= 7, 1 <= M <=10^9).

    Ouput

    For each case, if it's impossible to visit every room exactly once and get to the bottom left room, output "Impossible". Otherwise, output the number of tours as it describe above. Beacause the answer can be huge, you just need to output the answer MOD 7777777.

    Sample Input

    3 2
    3 3
    4 10
    

    Sample Output

    Impossible
    2
    2329
    

    Author: WANG, Yelei
    Source: ZOJ Monthly, September 2009

    看了几个大牛的博客。。基本上算是懂了。。

    Codes:

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<cstdio>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 using namespace std;
     10 const int N = 1010;
     11 const int Hash = 407;
     12 const int Mod = 7777777;
     13 #define For(i,n) for(int i=1;i<=n;i++)
     14 #define Rep(i,l,r) for(int i=l;i<=r;i++)
     15 #define Down(i,r,l) for(int i=r;i>=l;i--)
     16 
     17 struct STATEDP{
     18     int size,st[N],head[Hash],next[N];
     19     void clear(){size=0;memset(head,-1,sizeof(head));}
     20     int push(int state){
     21         int p,Key = state % Hash;
     22         for(p = head[Key];p!=-1;p=next[p])
     23             if(st[p]==state)  return p;    
     24         st[size]=state;next[size]=head[Key];head[Key]=size++;
     25         return (size-1);
     26     }
     27 }dp;
     28 
     29 struct Matrix{
     30     long long A[140][140];
     31     void clear(){memset(A,0,sizeof(A));}
     32 }Unit,Ans;
     33 
     34 int m,n,code[20];
     35 
     36 int encode(){
     37     int cnt=1 , h[20];
     38     memset(h,-1,sizeof(h));h[0]=0;
     39     int st=0;
     40     Rep(i,0,n-1){
     41         if(h[code[i]]==-1) h[code[i]]=cnt++;
     42         code[i]=h[code[i]];
     43         st<<=2;st|=code[i];
     44     }
     45     return st;
     46 }
     47 
     48 void decode(int st){
     49     Down(i,n-1,0) code[i] = st&3 , st>>=2;
     50 }
     51 
     52 void init(){
     53     Ans.clear();Unit.clear();
     54     dp.clear();dp.push(0);
     55     memset(code,0,sizeof(code));
     56     code[0] = code[n-1] = 1;
     57     dp.push(encode());
     58 }
     59 
     60 Matrix operator *(Matrix A,Matrix B){
     61     Matrix C;C.clear();
     62     Rep(i,0,dp.size-1)
     63       Rep(j,0,dp.size-1)
     64         Rep(k,0,dp.size-1)
     65           C.A[i][k]=(C.A[i][k] + (long long)(A.A[i][j] % Mod * B.A[j][k] % Mod)) % Mod;
     66     return C;
     67 }
     68 
     69 void Quick(){
     70     while(m){
     71         if(m&1) Ans = Ans * Unit;
     72         Unit = Unit * Unit;
     73         m>>=1;
     74     }    
     75     if(Ans.A[1][0]) printf("%lld
    ",Ans.A[1][0]);
     76     else            puts("Impossible");
     77 }
     78 
     79 
     80 bool Check(int st,int nst){
     81     decode(st);
     82     int up=0;
     83     int cnt=0;
     84     int k;
     85     Rep(i,0,n-1){
     86         if(up==0){
     87             if(code[i]==0&&(nst&(1<<i))==0)  return false;
     88             if(code[i]&&(nst&(1<<i)))continue;
     89             if(code[i]) up=code[i];
     90             else         up=-1;
     91             k=i;
     92         }
     93         else{
     94             if(code[i]&&(nst&(1<<i)))      return false;
     95             if(code[i]==0&&(nst&(1<<i))==0) continue;
     96             if(code[i]){
     97                 if(code[i]==up&&((nst!=0)||i!=n-1))return false; 
     98                 if(up>0){
     99                     Rep(j,0,n-1)
    100                       if(code[j]==code[i]&&j!=i) code[j]=code[k];
    101                     code[i]=code[k]=0;
    102                 }
    103                 else{
    104                     code[k]=code[i];code[i]=0;
    105                 }
    106             }
    107             else{
    108                 if(up>0)code[i]=code[k],code[k]=0;
    109                 else     code[i]=code[k]=n+(cnt++);
    110             }
    111             up=0;
    112         }
    113     }
    114     if(up!=0)return false;
    115     return true;
    116 }
    117 
    118 void DP(){
    119     For(i,dp.size-1)
    120         Rep(j,0,(1<<n))
    121             if(Check(dp.st[i],j)) 
    122                 Unit.A[i][dp.push(encode())] = 1;
    123     Rep(i,0,dp.size)  Ans.A[i][i] = 1;
    124     Quick();
    125 }
    126 
    127 int main(){
    128     while(~scanf("%d%d",&n,&m)){
    129         init();
    130         DP();
    131     }
    132     return 0;
    133 }
    codes
  • 相关阅读:
    ADO.NET Entity Framework如何:通过每种类型多个实体集定义模型(实体框架)
    ADO.NET Entity Framework EDM 生成器 (EdmGen.exe)
    编程之美的求阶乘结果末尾0的个数
    JS 自动提交表单时 报“对象不支持此属性”错误
    php168商务系统品牌无法生成的解决办法
    如何从Access 2000中表删除重复记录
    服务器IUSR_机器名账号找不到怎么办?
    SQL2005 重建全文索引步骤 恢复数据时用到
    PHP页面无法输出XML的解决方法
    bytes2BSTR 解决ajax中ajax.responseBody 乱码问题
  • 原文地址:https://www.cnblogs.com/zjdx1998/p/3918559.html
Copyright © 2011-2022 走看看