1. 程式人生 > >洛谷P2289 [HNOI2004]郵遞員(插頭dp)

洛谷P2289 [HNOI2004]郵遞員(插頭dp)

[] val struct ont bit eof using hash +=

傳送門

太神仙了……講不來講不來->這裏

  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 }

洛谷P2289 [HNOI2004]郵遞員(插頭dp)