zoukankan      html  css  js  c++  java
  • 插头$DP$初步

    之前学的全忘了,到头来又要重炒一遍板子,不过因为码力增强(认真抄),感觉思路清晰一点了。

    邮递员:

      放个注释的板子

      

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #define LL __int128
      6 using namespace std;
      7 int n,m;
      8 LL ans=0;
      9 struct HASH_MAP{
     10     #define mo 2601
     11     struct nnode{
     12         int nt,key;
     13         LL val;
     14     }e[mo*20];int hd[mo],itot;
     15     void init(){
     16         itot=0;
     17         memset(hd,0,sizeof(hd));
     18         return ;
     19     }
     20     LL &operator [](const int &key){
     21         const int u=key%mo;
     22         for(int i=hd[u];i;i=e[i].nt)
     23             if(e[i].key==key)return e[i].val;
     24         e[++itot].key=key,e[itot].val=0;
     25         e[itot].nt=hd[u],hd[u]=itot;
     26         return e[itot].val;
     27     }
     28 }f[2];
     29 int now=1,past=0;
     30 inline int Find(int sta,int pos){
     31     return (sta>>((pos-1)<<1))&3;
     32 }//四进制取位
     33 inline void Set(int &sta,int pos,int w){
     34     sta-=(Find(sta,pos)<<((pos-1)<<1));
     35     sta+=w<<((pos-1)<<1);
     36     return ;
     37 }//四进制位赋值
     38 //0无插头 1左括号插头 2右括号插头
     39 inline int Get(int sta,int pos){
     40     int knd=Find(sta,pos);
     41     if(knd==0)return pos;
     42     //自己是自己来省掉无插头
     43     int cnt=0;
     44     if(knd==1){//左括号往右找
     45         for(int i=pos,tmp;i<=m+1;++i){
     46             tmp=Find(sta,i);
     47             if(tmp==1)++cnt;
     48             if(tmp==2)--cnt;
     49             if(cnt==0)return i;
     50         }
     51     }
     52     else{
     53         for(int i=pos,tmp;i>=1;--i){
     54             tmp=Find(sta,i);
     55             if(tmp==1)++cnt;
     56             if(tmp==2)--cnt;
     57             if(cnt==0)return i;
     58         }
     59     }
     60     return -1;
     61 }//查找对应的插头,即括号匹配
     62 void wk(int x,int y){//将轮廓线扩过这个格子
     63     int lim=f[past].itot;
     64     f[now].init();
     65     for(int i=1;i<=lim;++i){
     66         int sta=f[past].e[i].key;
     67         LL val=f[past].e[i].val;
     68         int p1=Find(sta,y),p2=Find(sta,y+1);
     69         //左边的格子的插头,上边格子的插头
     70         int g1=Get(sta,y),g2=Get(sta,y+1);
     71         if(g1==-1||g2==-1)//没有对应插头,不合法
     72             continue;
     73         if(!p1&&!p2){//新建两个插头
     74             if(x!=n&&y!=m){
     75                 Set(sta,y,1);
     76                 Set(sta,y+1,2);
     77                 f[now][sta]+=val;
     78             }
     79         }
     80         else if(!p1&&p2){//要么向下,要么向右
     81             if(y!=m)f[now][sta]+=val;
     82             if(x!=n){
     83                 Set(sta,y,p2);
     84                 Set(sta,y+1,0);
     85                 f[now][sta]+=val;
     86             }
     87         }
     88         else if(p1&&!p2){//同上
     89             if(x!=n)f[now][sta]+=val;
     90             if(y!=m){
     91                 Set(sta,y,0);
     92                 Set(sta,y+1,p1);
     93                 f[now][sta]+=val;
     94             }
     95         }
     96         else if(p1==1&&p2==1){//交换p2和p2对应插头的类型,使p1和p2能拼在一起
     97             Set(sta,g2,1);
     98             Set(sta,y,0);
     99             Set(sta,y+1,0);
    100             f[now][sta]+=val;
    101         }
    102         else if(p1==2&&p2==2){//同上
    103             Set(sta,g1,2);
    104             Set(sta,y,0);
    105             Set(sta,y+1,0);
    106             f[now][sta]+=val;
    107         }
    108         else if(p1==1&&p2==2){
    109             if(x==n&&y==m)
    110                 ans+=val;
    111         }
    112         else if(p1==2&&p2==1){//交换p1和p2的类型
    113             Set(sta,y,0);
    114             Set(sta,y+1,0);
    115             f[now][sta]+=val;
    116         }
    117     }
    118     now=past,past^=1;
    119     return ;
    120 }
    121 void pt(LL x){
    122     if(!x)return ;
    123     pt(x/10);
    124     putchar(x%10+'0');
    125     return ;
    126 }
    127 int main(){
    128     //freopen("da.in","r",stdin);
    129     
    130     cin>>n>>m;
    131     if(n==1||m==1)puts("1"),exit(0);
    132     if(m>n)m^=n,n^=m,m^=n;
    133     f[0].init();f[1].init();
    134     f[0][0]=1;
    135     for(int i=1;i<=n;++i){
    136         for(int j=1;j<=m;++j)wk(i,j);
    137         if(i!=n){
    138             int lim=f[past].itot;
    139             for(int j=1;j<=lim;++j)
    140                 f[past].e[j].key<<=2;
    141             //转到下一行,多一个位表示新增的墙角
    142         }
    143     }
    144     ans+=ans;
    145     //cout<<ans<<endl;
    146     if(!ans)puts("0"),exit(0);
    147     pt(ans);
    148     
    149     return 0;
    150 }
    151 //工业化代码应该还是好调一些的
    152 //ladylex学长的板子
    153 //之前打的板子已经不会了

     

  • 相关阅读:
    go 资料
    BW:如何加载和生成自定义的层次结构,在不使用平面文件的SAP业务信息仓库
    权限变量 --转载
    BW CUBE 数据的聚集和压缩
    BW基于ALE的主数据增量机制分析
    SAP-GR/IR的理解
    SDN论坛看到BW的问题及相关解答
    Step by step Process of creating APD
    处理链方式执行APD处理
    BW标准数据源初始化设置
  • 原文地址:https://www.cnblogs.com/2018hzoicyf/p/12021757.html
Copyright © 2011-2022 走看看