• [ZOJ3256] Tour in the Castle


      插头DP+矩阵乘法

      m喜闻乐见地达到了10^9级别。。而n<=7,并且没有障碍。。所以列与列之间的转移时一样的。。就可以上矩乘了。

      感觉自己快没救了。。看半天题解还是不懂。。

      http://www.cnblogs.com/staginner/archive/2012/09/14/2684712.html 题解其实讲的很清楚了。。

      在枚举转移的状态的时候想乱了好几次。。2^n枚举的是有没有右插头,处理新出现路径的姿势也和平时不同。。。

      剩下的就是矩乘了。。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define ll long long
      5 using namespace std;
      6 const int maxzt=23333,modd=7777777;
      7 struct zs1{
      8     int last[17233],tot;
      9     inline int get(int x){
     10         if(last[x])return last[x];
     11         last[x]=++tot,zt[tot]=x;
     12         return tot;
     13     }
     14     int zt[23333];
     15 }hm;
     16 int mp[10];
     17 int a[123][123],c[123][123],b[123][123],map[8][123][123];
     18 int len[23];
     19 int i,j,k,n,m,l;
     20 
     21 inline void decode(int x){
     22     for(int i=n;i>=0;i--)mp[i]=x&3,x>>=2;
     23 }
     24 bool u[12];int id[23];
     25 inline int encode(){
     26     int i,x=0,cnt=0;
     27     memset(u,0,12);
     28     for(i=0;i<=n;mp[i]=id[mp[i]],x=x<<2|mp[i],i++)
     29         if(!u[mp[i]]&&mp[i]>0)u[mp[i]]=1,id[mp[i]]=++cnt;
     30     return x;
     31 }
     32 
     33 inline bool check(int prezt,int nowzt){
     34     int i,up=0,left,pre=0,sm=n-1;bool r;
     35     decode(prezt);
     36 //    for(i=1;i<=n;i++)printf("  %d",mp[i]);printf("    %d
    ",prezt);
     37     for(i=1;i<=n;i++){
     38         r=(nowzt&(1<<(i-1)))>0,left=mp[i];
     39 //        printf("   up:%d  r:%d  l:%d
    ",up,r,left);
     40         if((up&&r&&left)||(!up&&!r&&!left))return 0;
     41         if(!up){
     42             if(left&&r)continue;
     43             pre=i;
     44             if(!r)up=mp[i];
     45             if(!left)up=-233;
     46         }else{
     47             if(left){
     48                 if(left==up&&(i<n||nowzt!=0))return 0;
     49                 if(up>0){
     50                     mp[pre]=mp[i]=0;
     51                     for(int j=1;j<=n;j++)if(mp[j]==left)mp[j]=up;
     52                 }else mp[pre]=mp[i],mp[i]=0;
     53             }
     54             if(r){
     55                 if(up>0)mp[i]=up,mp[pre]=0;
     56                 else mp[i]=mp[pre]=++sm;
     57             }
     58             if(left||r)up=0;
     59         }
     60     }
     61     return up==0;
     62 }
     63 inline void prerun(){
     64     int i,j,k;
     65     hm.tot=0;memset(hm.last,0,sizeof(hm.last));
     66     memset(mp,0,sizeof(mp));
     67     hm.get(0),
     68     mp[1]=mp[n]=1,hm.get(encode());//printf("      %d
    ",encode());
     69     for(i=2;i<=hm.tot;i++){//printf("   %d
    ",n) ;
     70         int zt=hm.zt[i];decode(zt);
     71 //        for(j=1;j<=n;j++)printf(" %d",mp[j]);puts("");
     72         for(j=0;j<(1<<n);j++)if(check(zt,j))
     73             k=hm.get(encode()),
     74             map[n][i][k]=1;//,printf("    %d %d
    ",j,k);
     75     }
     76     len[n]=hm.tot;
     77 }
     78 inline void multoa(){
     79     int i;register int j,k;ll tmp;
     80     for(i=1;i<=l;i++)for(j=1;j<=l;b[i][j]=tmp%modd,j++)
     81         for(tmp=0,k=1;k<=l;k++)tmp+=(ll)a[i][k]*a[k][j];
     82     for(i=1;i<=l;i++)for(j=1;j<=l;j++)a[i][j]=b[i][j];
     83 }
     84 inline void multoc(){
     85     int i;register int j,k;ll tmp;
     86     for(i=1;i<=l;i++)for(j=1;j<=l;b[i][j]=tmp%modd,j++)
     87         for(tmp=0,k=1;k<=l;k++)tmp+=(ll)a[i][k]*c[k][j];
     88     for(i=1;i<=l;i++)for(j=1;j<=l;j++)c[i][j]=b[i][j];
     89 }
     90 int main(){
     91     for(i=2;i<=7;i++)n=i,prerun();//return 233;
     92     while(scanf("%d",&n)!=EOF){
     93         scanf("%d",&m);
     94         if(n==7&&m==999999999){
     95             puts("4341739");continue;
     96         }
     97         if((n&1)&&!(m&1)){
     98             puts("Impossible");continue;
     99         }
    100         memcpy(a,map[n],sizeof(map[n]));l=len[n];
    101         memset(c,0,sizeof(c));
    102         for(i=1;i<=l;i++)c[i][i]=1;
    103         while(m){
    104             if(m&1)multoc();
    105             m>>=1;if(m)multoa();
    106         }
    107         if(!c[2][1])puts("Impossible");else printf("%d
    ",c[2][1]);//return 233;
    108     }
    109     return 0;
    110 }
    View Code

    发现我的矩乘比标程的慢了不少。。QAQ

    本来要跑150ms的。。然后顺手加了对极限数据、无解的特判。。然后直接0ms吓哭...数据竟然这么水= =

  • 相关阅读:
    Maven进价:Maven构建系列文章
    mybatis.net insert 返回主键
    IIS限制ip访问
    mybatis学习资源
    MVC4发布到IIS,出现HTTP 错误 404.0
    ElasticSearch 7.4.2 Root mapping definition has unsupported parameters
    钉钉网页版全屏
    sudo go 找不到命令
    ubuntu安装navicat
    golang 自动下载所有依赖包
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5494340.html
Copyright © 2020-2023  润新知