• [FZU1977] Pandora adventure


      来学插头DP了= =

      GDKOI前觉得不会考数位DP,GDOI前觉得插头DP用不上。。

      结果令人伤感>_<

      这题并不用增加状态。。

      只要在形成环的时候,让形成环的位置在最后一个必走点之后,并且此时只有一个联通分量。

      因为必走点处肯定有插头。。所以只有一个联通分量就意味着所有必走点都连在一起了。

      选择经过的点就在转移的时候多一种方法。。。

    学的是最小表示法。。又长又慢TAT。。跳错坑了= =

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define ull unsigned long long
      5 using namespace std;
      6 const int modd=2333,maxzt=123333;
      7 struct zs{
      8     struct hash{
      9         ull too;int pre;
     10     }e[maxzt];int tot,last[modd];
     11     ull f[maxzt],zt[maxzt];
     12     
     13     inline int get(ull v){
     14         int i,x=v%modd;
     15         for(i=last[x];i&&e[i].too!=v;i=e[i].pre);
     16         if(i&&e[i].too==v)return i;
     17         e[++tot].too=v,e[tot].pre=last[x],last[x]=tot;
     18         zt[tot]=v;f[tot]=0;
     19         return tot;
     20     }
     21 }hm[2];
     22 int i,j,k,n,m,tx,ty;
     23 int can[14][14];
     24 ull ans;
     25 char s[23];
     26 int v[2333];
     27 
     28 inline void clr(bool now){
     29     memset(hm[now].last,0,modd<<2),
     30     hm[now].tot=0;
     31 }
     32 
     33 bool u[8];int id[8],mp[13];
     34 inline ull encode(){
     35     memset(u,0,8);
     36     ull x=0;int tt=0;
     37     for(int i=0;i<=m;mp[i]=id[mp[i]],x=x<<3|mp[i],i++)
     38         if(mp[i]&&!u[mp[i]])u[mp[i]]=1,id[mp[i]]=++tt;
     39     return x;
     40 }
     41 inline void decode(ull x){
     42     for(int i=m;i>=0;i--)mp[i]=x&7,x>>=3;
     43 }
     44 inline void shift(){
     45     for(int i=m;i;i--)mp[i]=mp[i-1];
     46     mp[0]=0;
     47 }
     48 
     49 inline void dp_blank(int x,int y,bool pre){
     50     int i,left,up,j;bool now=pre^1;ull zt,f;
     51     clr(now);
     52     for(i=1;i<=hm[pre].tot;i++){
     53         zt=hm[pre].zt[i],f=hm[pre].f[i],
     54         decode(zt);
     55         left=mp[y-1],up=mp[y];
     56         if(!left&&!up){
     57             if(can[x+1][y]&&can[x][y+1]){
     58                 mp[y-1]=mp[y]=7;
     59                 if(y==m)shift();
     60                 hm[now].f[ hm[now].get(encode()) ]+=f;
     61             }
     62             if(can[x][y]==2){
     63                 mp[y-1]=mp[y]=0;
     64                 if(y==m)shift();
     65                 hm[now].f[ hm[now].get(encode()) ]+=f;
     66             }
     67         }
     68         if((!left)^(!up)){
     69             j=left|up;
     70             if(can[x+1][y]){
     71                 mp[y-1]=j,mp[y]=0;
     72                 if(y==m)shift();
     73                 hm[now].f[ hm[now].get(encode()) ]+=f;
     74             }
     75             if(can[x][y+1]){
     76                 mp[y-1]=0,mp[y]=j;
     77                 if(y==m)shift();
     78                 hm[now].f[ hm[now].get(encode()) ]+=f;
     79             }
     80         }
     81         if(left&&up){
     82             if(left==up)
     83                 if(x>tx||(x==tx&&y>=ty)){
     84                     mp[y-1]=mp[y]=0;
     85                     if(encode()==0)ans+=f;
     86                 }else;
     87             else{
     88                 mp[y-1]=mp[y]=0;
     89                 for(j=0;j<=m;j++)if(mp[j]==up)mp[j]=left;
     90                 if(y==m)shift();
     91                 hm[now].f[ hm[now].get(encode()) ]+=f;
     92             }
     93         }
     94     }
     95 }
     96 inline void dp_bar(int x,int y,bool pre){
     97     int i,left,up;bool now=pre^1;ull f,zt;
     98     clr(now);
     99     for(i=1;i<=hm[pre].tot;i++){
    100         zt=hm[pre].zt[i],f=hm[pre].f[i];
    101         decode(zt);
    102         left=mp[y-1],up=mp[y];
    103         if(!left&&!up){
    104             if(y==m)shift();
    105             hm[now].f[ hm[now].get(encode()) ]+=f;
    106         }
    107     }
    108 }
    109 
    110 int main(){
    111     int TT;
    112     scanf("%d",&TT);v['X']=0,v['O']=1,v['*']=2;
    113     for(int TTT=1;TTT<=TT;TTT++){
    114         scanf("%d%d",&n,&m);
    115         memset(can,0,sizeof(can));
    116         for(i=1;i<=n;i++)
    117             for(scanf("%s",s+1),j=1;j<=m;j++){
    118                 can[i][j]=v[s[j]];
    119                 if(s[j]=='O')tx=i,ty=j;
    120             }
    121         
    122         for(i=n,j=0;i;i--){
    123             for(j=m;j;j--)if(can[i][j]==1)break;
    124             if(j>0)break;
    125         }
    126         tx=i,ty=j;
    127         
    128         bool now=1,pre=0;ans=0;
    129         clr(0),hm[pre].f[ hm[pre].get(0) ]=1;
    130         for(i=1;i<=n;i++)for(j=1;j<=m;j++,swap(now,pre))
    131             if(can[i][j])dp_blank(i,j,pre);else dp_bar(i,j,pre);
    132         printf("Case %d: %I64u
    ",TTT,ans);
    133     }
    134     return 0;
    135 }
    View Code
  • 相关阅读:
    通过Math.atan2计算角度 改变物体朝向
    table.sort 排序的问题
    shader 实现正旋波效果 水面波动效果
    第一篇碎碎心得
    ping 整理
    路由器
    C语言里如何读取位数据的某几位?
    ubunut命令
    基于SPIflash 的fatfs调试步骤
    makefile 学习总结--函数
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5485593.html
Copyright © 2020-2023  润新知