URAL 1519 Formula 1
第一个插头DP,看了CDQ的论文看的一知半解,更不要说些代码了。真的写不来啊。orz orz orz
参考的这位大神:http://hi.baidu.com/longmenwaideyu/item/0a11a033eb04db92b80c038c
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 15; 6 const int HASH = 30007; 7 const int SIZE = 1000010; 8 typedef long long LL; 9 int N,M,maze[maxn][maxn],code[maxn],ch[maxn],ex,ey; 10 char b[maxn]; 11 12 struct Hashmap{ 13 int e,first[HASH],next[SIZE]; 14 LL state[SIZE],f[SIZE]; 15 16 void init(){ 17 e = 0; 18 memset(first,-1,sizeof(first)); 19 } 20 21 void push(LL st,LL ans){ 22 int h = st%HASH; 23 for(int i = first[h];i != -1;i = next[i]) 24 if(state[i] == st){ 25 f[i] += ans; 26 return; 27 } 28 state[e] = st; 29 f[e] = ans; 30 next[e] = first[h]; 31 first[h] = e++; 32 } 33 }dp[2]; 34 35 void update(int *code,int len){ 36 for(int i = len;i >= 1;i--) 37 code[i] = code[i-1]; 38 code[0] = 0; 39 } 40 41 void decode(int *code,int len,LL st){ 42 for(int i = len;i >= 0;i--){ 43 code[i] = st&7; 44 st >>= 3; 45 } 46 } 47 48 LL encode(int *code,int len){ 49 int cnt = 1; 50 memset(ch,-1,sizeof(ch)); 51 ch[0] = 0; 52 LL st = 0; 53 for(int i = 0;i <= len;i++){ 54 if(ch[code[i]] == -1){ 55 ch[code[i]] = cnt++; 56 } 57 code[i] = ch[code[i]]; 58 st <<= 3; 59 st |= code[i]; 60 } 61 return st; 62 } 63 64 void dpblank(int i,int j,int now,int pre){ 65 int left,up,t; 66 for(int k = 0;k < dp[pre].e;k++){ 67 decode(code,M,dp[pre].state[k]); 68 left = code[j-1],up = code[j]; 69 70 if(left && up){ 71 if(left == up){ 72 if(i == ex && j == ey){ 73 code[j-1] = code[j] = 0; 74 if(j == M) update(code,M); 75 dp[now].push(encode(code,M),dp[pre].f[k]); 76 } 77 } 78 else{ 79 code[j-1] = code[j] = 0; 80 for(t = 0;t <= M;t++){ 81 if(code[t] == up) code[t] = left; 82 } 83 if(j == M) update(code,M); 84 dp[now].push(encode(code,M),dp[pre].f[k]); 85 } 86 }else if((!left && up) ||(left && !up)){ 87 if(left) t = left; 88 else t = up; 89 if(maze[i][j+1]){ 90 code[j-1] = 0,code[j] = t; 91 dp[now].push(encode(code,M),dp[pre].f[k]); 92 } 93 if(maze[i+1][j]){ 94 code[j-1] = t,code[j] = 0; 95 if(j == M) update(code,M); 96 dp[now].push(encode(code,M),dp[pre].f[k]); 97 } 98 }else{ 99 if(maze[i+1][j] && maze[i][j+1]){ 100 code[j-1] = code[j] = 13; 101 dp[now].push(encode(code,M),dp[pre].f[k]); 102 } 103 } 104 } 105 } 106 107 void dpblock(int i,int j,int now,int pre){ 108 for(int k = 0;k < dp[pre].e;k++){ 109 decode(code,M,dp[pre].state[k]); 110 code[j-1] = code[j] = 0; 111 if(j == M) update(code,M); 112 dp[now].push(encode(code,M),dp[pre].f[k]); 113 } 114 } 115 116 int main() 117 { 118 while(scanf("%d%d",&N,&M) != EOF){ 119 memset(maze,0,sizeof(maze)); 120 ex = 0; 121 for(int i = 1;i <= N;i++){ 122 scanf("%s",b+1); 123 for(int j = 1;j <= M;j++) 124 if(b[j] == '.') maze[ex=i][ey=j] = 1; 125 } 126 if(ex == 0){ 127 printf("0\n"); 128 continue; 129 } 130 int now = 0,pre = 1; 131 dp[now].init(); 132 dp[now].push(0,1); 133 for(int i = 1;i <= N;i++){ 134 for(int j = 1;j <= M;j++){ 135 swap(now,pre); 136 dp[now].init(); 137 if(maze[i][j]) dpblank(i,j,now,pre); 138 else dpblock(i,j,now,pre); 139 } 140 } 141 LL ans = 0; 142 for(int i = 0;i < dp[now].e;i++) 143 ans += dp[now].f[i]; 144 printf("%I64d\n",ans); 145 } 146 return 0; 147 }