码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3377 插头dp

时间:2015-08-14 20:55:32      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

 题目大意:

从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了

 

这里有个思路是转化成熟悉的回路问题

在上方和右方最外围定义一圈权值为0 , 那么我们相当于从定义以后的左上角开始经过所有外围点形成的回路,那么去掉最外围的0,剩下的就是(1,1)-》(n,n)的权值和了

但是这里最外围的点的插头具有特殊性,每次到最外围的点,你左和上有且仅有一个插头,而且出去的方向必然是下一个最外围的点

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 
  6 using namespace std;
  7 #define ll long long
  8 const int HASH = 10007;
  9 const int STATE = 1000010;
 10 const int MAXD = 15;
 11 int  n , m;
 12 int code[MAXD] , mp[MAXD][MAXD];
 13 bool flag[MAXD][MAXD];//标记位,标记当前点能否作为最终点
 14 ll ans = 0;
 15 int w[MAXD][MAXD];
 16 struct HASHMAP{
 17     int head[HASH] , next[STATE] , state[STATE] , size;
 18     ll f[STATE];
 19 
 20     void init(){
 21         size = 0;
 22         memset(head , -1 , sizeof(head));
 23     }
 24 
 25     void push_in(int st , ll sum){
 26         int h = st%HASH;
 27         for(int i = head[h] ; ~i ; i=next[i]){
 28             if(st == state[i]){
 29                 f[i]=max(f[i] , sum); //这题目为求最大值
 30                 return ;
 31             }
 32         }
 33         f[size]=sum;
 34         state[size] = st;
 35         next[size] = head[h];
 36         head[h] = size++;
 37     }
 38 }hashmap[2];
 39 
 40 int num = 0;//记录共有的插头数量
 41 void decode(int *code , int m , int st)
 42 {
 43     num = 0;
 44     for(int i=m ; i>=0 ; i--){
 45         code[i] = st&3;
 46         st>>=2;
 47         if(code[i]) num++;
 48     }
 49 }
 50 
 51 int encode(int *code , int m)
 52 {
 53     int st=0;
 54     for(int i=0 ; i<=m ; i++){
 55         st<<=2;
 56         st |= code[i];
 57     }
 58     return st;
 59 }
 60 
 61 void shift(int *code , int m) //换行,可理解为将最右侧轮廓线换到了下一行的最左侧
 62 {
 63     for(int i=m ; i>=0 ; i--) code[i] = code[i-1];
 64     code[0] = 0;
 65 }
 66 
 67 void dpblank(int i , int j , int cur)
 68 {
 69     int k , left , up;
 70     for(k=0 ; k<hashmap[cur].size ; k++){
 71         decode(code , m , hashmap[cur].state[k]);
 72         left = code[j-1];
 73         up = code[j];
 74         if(!left && !up){
 75             if(mp[i][j]==2) continue;
 76             if(mp[i][j]==1){
 77                 if(j == m) shift(code , m);
 78                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
 79             }
 80             if(mp[i][j+1] && mp[i+1][j]){
 81                 code[j-1] = 1 , code[j] = 2;
 82                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
 83             }
 84         }
 85         else if(!left && up){
 86             if(mp[i][j]==2 && (up!=2)) continue;
 87             else if(mp[i][j]==2){
 88                 if(mp[i][j+1]==2) hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
 89                 else{
 90                     code[j-1] = up , code[j] = 0;
 91                     if(j == m) shift(code , m);
 92                     hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
 93                 }
 94                 continue;
 95             }
 96             if(mp[i][j+1]) hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
 97             if(mp[i+1][j]){
 98                 code[j-1] = up , code[j] = 0;
 99                 if(j == m) shift(code , m);
100                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
101             }
102         }
103         else if(left && !up){
104             if(mp[i][j]==2 && (left!=2)) continue;
105             else if(mp[i][j]==2){
106                 if(mp[i][j+1]==2){
107                     code[j-1] = 0 , code[j] = left;
108                     hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
109                 }else{
110                     if(j == m)  shift(code , m);
111                     hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
112                 }
113                 continue;
114             }
115             if(mp[i+1][j]){
116                 if(j == m)  shift(code , m);
117                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
118             }
119             if(mp[i][j+1]){
120                 code[j-1] = 0 , code[j] = left;
121                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
122             }
123         }
124         else if(mp[i][j]==2) continue;
125         else if(left==1 && up == 1){
126             int cnt = 1;
127             for(int v=j+1 ; v<=m ; v++){
128                 if(code[v]==1)cnt++;
129                 if(code[v]==2)cnt--;
130                 if(!cnt){
131                     code[v]=1;
132                     break;
133                 }
134             }
135             code[j-1] = code[j] = 0;
136             if(j == m) shift(code , m);
137             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
138         }
139         else if(left == 2 && up == 2){
140             int cnt=1;
141             for(int v=j-2 ; v>=1 ; v--){
142                 if(code[v]==2)cnt++;
143                 if(code[v]==1)cnt--;
144                 if(!cnt){
145                     code[v]=2;
146                     break;
147                 }
148             }
149             code[j-1] = code[j] = 0;
150             if(j == m) shift(code , m);
151             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
152         }
153         else if(left==1 && up==2){
154             if(i==n && j==m) ans=max(ans,hashmap[cur].f[k]+w[i][j]);
155         }
156         else{
157             code[j-1]=code[j]=0;
158             if(j == m) shift(code , m);
159             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]);
160         }
161     }
162 }
163 
164 void init()
165 {
166     for(int i=1 ; i<=m+1 ; i++) mp[1][i]=2 , w[1][i] = 0;
167     for(int i=2 ; i<=n+1 ; i++){
168         for(int j=1 ; j<=m ; j++)
169             scanf("%d" , &w[i][j]) , mp[i][j]=1;
170         w[i][m+1] = 0 , mp[i][m+1] = 2;
171         mp[i][m+2] = mp[n+2][i]=0;
172     }
173 
174     n++ , m++;
175     mp[1][1] = mp[n][m] = 1;
176     /*for(int i=1 ; i<=n ; i++){
177         for(int j=1 ;j <=m ; j++){
178             cout<<mp[i][j]<<" ";
179         }
180         cout<<endl;
181     }*/
182 }
183 
184 ll solve()
185 {
186     ans = -1e9;
187     int cur = 0;
188     hashmap[cur].init();
189     hashmap[cur].push_in(0 , 0);
190     for(int i=1 ; i<=n ; i++){
191         for(int j=1 ; j<=m ; j++){
192             hashmap[cur^1].init();
193             dpblank(i , j , cur);
194             cur ^= 1;
195           /* cout<<"test: "<<i<<" "<<j<<endl;
196                 for(int k=0 ; k<hashmap[cur].size ; k++)
197                 cout<<hashmap[cur].f[k]<<endl;*/
198 
199         }
200     }
201    // for(int i=0 ; i<hashmap[cur].size ; i++)
202     return ans;
203 }
204 
205 int main()
206 {
207   //  freopen("in.txt" , "r" , stdin);
208     int cas = 0;
209     while(~scanf("%d%d" , &n , &m))
210     {
211         init();
212         printf("Case %d: ",++cas);
213         if(n==1 && m==1){
214             printf("%d\n" , w[1][1]);
215             continue;
216         }
217         printf("%I64d\n" , solve());
218     }
219     return 0;
220 }

 

HDU 3377 插头dp

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4730904.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!