zoukankan      html  css  js  c++  java
  • HDU 3377 插头dp

     题目大意:

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

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

    在上方和右方最外围定义一圈权值为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
    " , w[1][1]);
    215             continue;
    216         }
    217         printf("%I64d
    " , solve());
    218     }
    219     return 0;
    220 }
  • 相关阅读:
    排查程序死循环,死锁的方法 ——pstack
    可变参数使用
    snprintf 返回值陷阱 重新封装
    linux 查看cpu个数,内存情况,系统版本
    nginx取结构体地址
    fuser命令使用心得
    Linux中dos2unix批量转换
    rpm中config,config(noreplace)区别
    slowhttptest慢攻击工具介绍
    jmeter性能测试
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4730904.html
Copyright © 2011-2022 走看看