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 }
View Code

 

posted @ 2013-12-02 19:41  浙西贫农  阅读(356)  评论(2编辑  收藏  举报