洛谷P2289 [HNOI2004]邮递员(插头dp)

传送门

太神仙了……讲不来讲不来->这里

  1 //minamoto
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cmath>
  6 #define ll long long
  7 using namespace std;
  8 const int cube=1e9,mod=2601;
  9 int n,m;
 10 struct node{
 11     int bit[6];
 12     inline void clear(){memset(bit,0,sizeof(bit));}
 13     node(){clear();}
 14     inline void set(int t){clear();while(t)bit[++bit[0]]=t%cube,t/=cube;}
 15     inline int &operator [](int x){return bit[x];}
 16     inline void print(){
 17         printf("%d",bit[bit[0]]);
 18         for(int i=bit[0]-1;i;--i) printf("%09d",bit[i]);
 19         putchar(10);
 20     }
 21     inline node operator +(node b){
 22         node c;
 23         c[0]=max(bit[0],b[0])+1;
 24         for(int i=1;i<=c[0];++i)
 25         c[i]+=bit[i]+b[i],c[i+1]+=c[i]/cube,c[i]%=cube;
 26         while(!c[c[0]]) --c[0];
 27         return c;
 28     }
 29     inline void operator +=(node b){*this=*this+b;}
 30     inline void operator =(int x){set(x);}
 31 }ans;
 32 struct Ha{
 33     node val[mod];
 34     int key[mod],sz,Hash[mod];
 35     inline void init(){
 36         memset(val,0,sizeof(val)),memset(key,-1,sizeof(key));
 37         sz=0,memset(Hash,0,sizeof(Hash));
 38     }
 39     inline void newhash(int id,int v){Hash[id]=++sz,key[sz]=v;}
 40     node &operator [](const int state){
 41         for(int i=state%mod;;i=(i+1==mod)?0:i+1){
 42             if(!Hash[i]) newhash(i,state);
 43             if(key[Hash[i]]==state) return val[Hash[i]];
 44         }
 45     }
 46 }f[2];
 47 inline int find(int state,int id){return (state>>((id-1)<<1))&3;}
 48 inline void set(int &state,int bit,int val){bit=(bit-1)<<1,state|=3<<bit,state^=3<<bit,state|=val<<bit;}
 49 int link(int state,int pos){
 50     int cnt=0,del=(find(state,pos)==1)?1:-1;
 51     for(int i=pos;i&&i<=m+1;i+=del){
 52         int plug=find(state,i);
 53         if(plug==1) ++cnt;
 54         else if(plug==2) --cnt;
 55         if(!cnt) return i;
 56     }
 57     return -1;
 58 }
 59 void solve(int x,int y){
 60     int now=((x-1)*m+y)&1,last=now^1,tot=f[last].sz;
 61     f[now].init();
 62     for(int i=1;i<=tot;++i){
 63         int state=f[last].key[i];
 64         node val=f[last].val[i];
 65         int plug1=find(state,y),plug2=find(state,y+1);
 66         if(link(state,y)==-1||link(state,y+1)==-1) continue;
 67         if(!plug1&&!plug2){if(x!=n&&y!=m)set(state,y,1),set(state,y+1,2),f[now][state]+=val;}
 68         else if(plug1&&!plug2){
 69             if(x!=n) f[now][state]+=val;
 70             if(y!=m) set(state,y,0),set(state,y+1,plug1),f[now][state]+=val;
 71         }
 72         else if(!plug1&&plug2){
 73             if(y!=m) f[now][state]+=val;
 74             if(x!=n)  set(state,y,plug2),set(state,y+1,0),f[now][state]+=val;
 75          }
 76          else if(plug1==1&&plug2==1)
 77          set(state,link(state,y+1),1),set(state,y,0),set(state,y+1,0),f[now][state]+=val;
 78          else if(plug1==1&&plug2==2){if(x==n&&y==m)ans+=val;}
 79          else if(plug1==2&&plug2==1)set(state,y,0),set(state,y+1,0),f[now][state]+=val;
 80          else if(plug1==2&&plug2==2)
 81          set(state,link(state,y),2),set(state,y,0),set(state,y+1,0),f[now][state]+=val;
 82     }
 83 }
 84 int main(){
 85 //    freopen("testdata.in","r",stdin);
 86     scanf("%d%d",&n,&m);
 87     if(n==1||m==1) return puts("1"),0;
 88     if(m>n) swap(n,m);
 89     f[0].init(),f[0][0]=1;
 90     for(int i=1;i<=n;++i){
 91         for(int j=1;j<=m;++j) solve(i,j);
 92         if(i!=n){
 93             int now=(i*m)&1,tot=f[now].sz;
 94             for(int j=1;j<=tot;++j)
 95             f[now].key[j]<<=2;
 96         }
 97     }
 98     ans+=ans,ans.print();
 99     return 0;
100 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9656757.html
今日推荐