zoukankan      html  css  js  c++  java
  • 插头dp总结

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<vector>
      5 #define mod 192617
      6 #define ll long long
      7 using namespace std;
      8 int n,m;
      9 int now,to;//滚动
     10 int hs[2][mod<<3];//hash
     11 ll wei[2][mod<<3];//
     12 int ne[2][mod<<3];//
     13 int he[2][mod];//(前向星)
     14 ll alans=0;
     15 vector<int>sta[2];//储存状态
     16 char s[17];
     17 void addstate(int state,ll val)//添加新状态
     18 {
     19     int k=state%mod;
     20     for(int i=he[to][k];i;i=ne[to][i])
     21     {
     22         if(hs[to][i]==state)
     23         {
     24             wei[to][i]+=val;
     25             return;
     26         }
     27     }
     28     sta[to].push_back(state);
     29     int t=sta[to].size();
     30     ne[to][t]=he[to][k];
     31     wei[to][t]=val;
     32     hs[to][t]=state;
     33     he[to][k]=t;
     34         
     35 }
     36 ll getval(int state)//查询某状态下权值
     37 {
     38     int k=state%mod;
     39     for(int i=he[now][k];i;i=ne[now][i])
     40         if(hs[now][i]==state)
     41             return wei[now][i];    
     42 }
     43 int get(int state,int l)//查询某状态下的某位置的插头类型
     44 {
     45     return (state>>(l<<1))&3;
     46 }
     47 int renew(int state,int l,int ss)//更新状态/插头类型
     48 {
     49     state|=3<<(l<<1);
     50     state^=3<<(l<<1);
     51     state|=ss<<(l<<1);
     52     return state;
     53 }
     54 int fr1to2(int state,int fr)//两个1插头撞到,找2插头
     55 {
     56     int p=0,k;
     57     for(int i=fr;i<=m+1;++i)
     58     {
     59         k=get(state,i);
     60         if(k==1)++p;
     61         if(k==2)--p;
     62         if(!p)return i;
     63     }
     64 }
     65 int fr2to1(int state,int fr)//两个2插头撞到,找1插头
     66 {
     67     int p=0,k;
     68     for(int i=fr;i;--i)
     69     {
     70         k=get(state,i);
     71         if(k==1)++p;
     72         if(k==2)--p;
     73         if(!p)return i;
     74     }
     75 }
     76 void pr(int state)//调试输出
     77 {
     78     for(int i=1;i<=m+1;++i)
     79     {
     80         printf("%d",get(state,i));
     81     }
     82     printf(" %lld
    ",getval(state));
     83 }
     84 void work(int h,int l)
     85 {
     86     int state,pl,pu;
     87     ll val,ans=0;
     88     now^=1;to^=1;
     89     printf("%d %d
    ",h,l);
     90     memset(he[to],0,sizeof(he[to]));sta[to].clear();
     91     switch(s[l])
     92     {
     93         case '.':{
     94             for(int i=0;i<sta[now].size();++i)
     95             {
     96                 state=sta[now][i];
     97                 val=getval(state);
     98                 pl=get(state,l);
     99                 pu=get(state,l+1);
    100                 pr(state);
    101                 if(!pl&&!pu)//又臭又长的分类讨论
    102                 {
    103                     state=renew(state,l,1);
    104                     state=renew(state,l+1,2);
    105                     addstate(state,val);
    106                 }
    107                 else if(!pl&&pu)
    108                 {
    109                     addstate(state,val);
    110                     state=renew(state,l,pu);
    111                     state=renew(state,l+1,0);
    112                     addstate(state,val);
    113                 }
    114                 else if(pl&&!pu)
    115                 {
    116                     addstate(state,val);
    117                     state=renew(state,l+1,pl);
    118                     state=renew(state,l,0);
    119                     addstate(state,val);
    120                 }
    121                 else if(pl==1&&pu==2)
    122                 {
    123                     state=renew(state,l+1,0);
    124                     state=renew(state,l,0);
    125                     if(!state)ans+=val;
    126                 }
    127                 else if(pl==2&&pu==1)
    128                 {
    129                     state=renew(state,l+1,0);
    130                     state=renew(state,l,0);
    131                     addstate(state,val);
    132                 }
    133                 else if(pl==1&&pu==1)
    134                 {
    135                     int pos=fr1to2(state,l+1);
    136                     state=renew(state,l+1,0);
    137                     state=renew(state,l,0);
    138                     state=renew(state,pos,1);
    139                     addstate(state,val);
    140                 }
    141                 else if(pl==2&&pu==2)
    142                 {
    143                     int pos=fr2to1(state,l);
    144                     state=renew(state,l+1,0);
    145                     state=renew(state,l,0);
    146                     state=renew(state,pos,2);
    147                     addstate(state,val);
    148                 }
    149             }
    150             alans=ans;
    151             break;
    152         }
    153         case '-':{
    154             for(int i=0;i<sta[now].size();++i)
    155             {
    156                 state=sta[now][i];
    157                 val=getval(state);
    158                 pl=get(state,l);
    159                 pu=get(state,l+1);
    160                 pr(state);
    161                 if(pl&&!pu)
    162                 {
    163                     state=renew(state,l+1,pl);
    164                     state=renew(state,l,0);
    165                     addstate(state,val);
    166                 }
    167             }
    168             break;
    169         }
    170         case '|':{
    171             for(int i=0;i<sta[now].size();++i)
    172             {
    173                 state=sta[now][i];
    174                 val=getval(state);
    175                 pl=get(state,l);
    176                 pu=get(state,l+1);
    177                 if(!pl&&pu)
    178                 {
    179                     state=renew(state,l,pu);
    180                     state=renew(state,l+1,0);
    181                     addstate(state,val);
    182                 }
    183             }
    184             break;
    185         }
    186         case '#':{
    187             for(int i=0;i<sta[now].size();++i)
    188             {
    189                 state=sta[now][i];
    190                 val=getval(state);
    191                 pl=get(state,l);
    192                 pu=get(state,l+1);
    193                 if(!pl&&!pu)addstate(state,val);
    194             }
    195             break;
    196         }
    197     }
    198 }
    199 void reset()//换行/行间转移
    200 {
    201     int state;ll val;
    202     now^=1;to^=1;
    203     memset(he[to],0,sizeof(he[to]));sta[to].clear();
    204     for(int i=0;i<sta[now].size();++i)
    205     {
    206         state=sta[now][i];
    207         val=getval(state);
    208         if(get(state,m+1))continue;
    209         addstate(state<<2,val);
    210     }
    211 }
    212 int main()
    213 {
    214     scanf("%d%d",&n,&m);
    215     to=1;now=0;
    216     addstate(0,1);
    217     for(int i=1;i<=n;++i)
    218     {
    219         scanf("%s",s+1);
    220         for(int j=1;j<=m;++j)work(i,j);
    221         reset();
    222     }
    223     cout<<alans<<endl;
    224 }

     其实这份代码并不完美,它会搜索一些冗余状态,导致程序跑得比较慢,对于极强的数据很容易被卡,正常题一般都能水过

    以上为模板,然而我早就不用这套了。。

    插头dp的题核心就在于插头的设计,以及两插头相撞时的处理方式。

    插头dp码长好像都挺长,其实都出在了撞插头时的分类讨论以及各种各样的状态处理函数。

    题方面的话,插头dp对思路要求不太高,就是恶心。一般会给你一个矩阵,或图之类的,一般行数都挺多,但列数范围不大

    在做一些网格题时插头dp可以用来拿部分分。

    然后:

    学习博客:https://www.cnblogs.com/LadyLex/p/7326874.html

    题目总结:https://www.cnblogs.com/Lrefrain/p/12004519.html

    插头dp就这么多,可能还是我做题少吧,以后刷的题多了,理解深刻了可能还会再更。

  • 相关阅读:
    [Windows Server 2003] 服务器安全加固
    [Windows Server 2008] 手工创建安全网站
    [Windows Server 2008] 服务器安全加固
    [Windows Server 2008] Apache+PHP安全设置
    [Windows Server 2008] DEDECMS(织梦)安全设置
    [Windows Server 2008] Serv-U安全设置
    [Windows Server 2008] Ecshop安全设置
    [Windows Server 2012] 手工创建安全网站
    [Windows Server 2012] 服务器安全加固
    [Windows Server 2012] Apache+PHP安全设置
  • 原文地址:https://www.cnblogs.com/loadingkkk/p/11259173.html
Copyright © 2011-2022 走看看