zoukankan      html  css  js  c++  java
  • HDU3377 Plan

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3377


    简单路径要求权值最大,那么为了回避括号序列单独插头的情况特判多,考虑使用最小表示法。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<cstring>
      8 using namespace std;
      9 #define maxn 21
     10 #define inf ((0x7fffffff)-1)
     11 #define llg int
     12 #define sizee 233
     13 #define maxnZT ((1<<20)+1)
     14 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     15 llg n,m,code[maxn],zt[2][maxnZT],v[2][maxnZT],g[110][110],size[2],now,ne,ans=inf*-1;
     16 llg maze[10][10],val[10][10],ch[22];
     17 void outcode(llg x){for (llg i=0;i<=m;i++) code[i]=x&3,x>>=2;}
     18 
     19 struct node
     20 {
     21     llg x,val,pos;
     22 };
     23 
     24 vector<node>a[2][sizee];
     25 
     26 void decode(llg x) {for (llg i=0;i<=m;i++) code[i]=x&7,x>>=3;}
     27 
     28 void encode(llg p,llg val)
     29 {
     30     for (llg i=0;i<=20;i++) ch[i]=-1;
     31     ch[0]=0;
     32     llg C=0;
     33     for (llg i=0;i<=m;i++)
     34     {
     35         if (ch[code[i]]==-1) ch[code[i]]=++C;
     36         code[i]=ch[code[i]];
     37     }
     38     llg x=0;
     39     for (llg i=0;i<=m;i++) x+=code[i]*(1<<(i*3));
     40     llg wz=x%sizee,E=a[p][wz].size();
     41     for (llg i=0;i<E;i++)
     42         if (a[p][wz][i].x==x)
     43         {
     44             a[p][wz][i].val=max(a[p][wz][i].val,val);
     45             v[p][a[p][wz][i].pos]=max(v[p][a[p][wz][i].pos],val);
     46             return ;
     47         }
     48     size[p]++;
     49     node NEW; NEW.x=x; NEW.val=val; NEW.pos=size[p];
     50     a[p][wz].push_back(NEW);
     51     zt[p][size[p]]=x; v[p][size[p]]=val;
     52 }
     53 
     54 void init_a(llg p){for (llg i=0;i<sizee;i++) a[p][i].clear(); size[p]=0;}
     55 
     56 
     57 void shift()///换行 移位
     58 {
     59     for(int i=m;i>0;i--)
     60         code[i]=code[i-1];
     61     code[0]=0;
     62 }
     63 
     64 
     65 void dp(llg x,llg y)
     66 {
     67     llg left,up,V;
     68     for (llg K=1;K<=size[now];K++)
     69     {
     70         decode(zt[now][K]);
     71         left=code[y-1],up=code[y];//左上插头
     72         V=v[now][K];
     73 //------------------------------------------------------------
     74         if ((x==1 && y==1))//开始位置
     75         {
     76             if (maze[x][y+1])//往左走
     77             {
     78                 code[y]=17,code[y-1]=0;
     79                 encode(ne,V+val[x][y]);
     80             }
     81             if (maze[x+1][y])//往下走
     82             {
     83                 code[y-1]=17,code[y]=0;
     84                 encode(ne,V+val[x][y]);
     85             }
     86             continue;
     87         }
     88 //------------------------------------------------------------
     89         if (x==n && y==m)//结束位置
     90         {
     91             if ((!left && up) || (left && !up))//必须有且仅有一个插头
     92             {
     93                 code[y]=code[y-1]=0;
     94                 bool pd=true;
     95                 for (llg t=0;t<=m;t++) if (code[t]) pd=false;
     96                 if (pd) ans=max(ans,V+val[x][y]);
     97             }
     98             continue;
     99         }
    100 //------------------------------------------------------------
    101         if (left && up)//插头合并
    102         {
    103             if (left!=up)//如果属于同一个连通块则非法(因为形成了环)
    104             {
    105                 code[y]=code[y-1]=0;
    106                 for (llg t=0;t<=m;t++) if (code[t]==up) code[t]=left;
    107                 if (y==m) shift();
    108                 encode(ne,V+val[x][y]);
    109             }
    110             continue;
    111         }
    112 //------------------------------------------------------------
    113         if (left || up)//延续原来的连通分量
    114         {
    115             llg tmp;
    116             if (left) tmp=left;else tmp=up;
    117             if (maze[x][y+1])
    118             {
    119                 code[y-1]=0,code[y]=tmp;
    120                 encode(ne,V+val[x][y]);
    121             }
    122             if (maze[x+1][y])
    123             {
    124                 code[y-1]=tmp,code[y]=0;
    125                 if (y==m) shift();
    126                 encode(ne,V+val[x][y]);
    127             }
    128         }
    129 //------------------------------------------------------------
    130         if (!left && !up)//没有插头,新建连通分量或者不走这一个格子
    131         {
    132             if (maze[x][y+1] && maze[x+1][y])
    133             {
    134                 code[y]=code[y-1]=17;
    135                 encode(ne,V+val[x][y]);
    136             }
    137             code[y]=code[y-1]=0;
    138             if (y==m) shift();
    139             encode(ne,V);
    140         }
    141     }
    142 }
    143 
    144 void work()
    145 {
    146     now=0,ne=0;
    147     encode(now,0);
    148     for (llg i=1;i<=n;i++)
    149     {
    150         for (llg j=1;j<=m;j++)
    151         {
    152             ne=now^1;
    153             init_a(ne);
    154             dp(i,j);
    155             now=ne;
    156         }
    157     }
    158 }
    159 
    160 void init()
    161 {
    162     memset(maze,0,sizeof(maze));
    163     for (llg i=1;i<=n;i++) 
    164         for (llg j=1;j<=m;j++)
    165             scanf("%d",&val[i][j]),maze[i][j]=1;
    166 }
    167 
    168 int main()
    169 {
    170     yyj("hdu3377");
    171     llg cas=0;
    172     while (scanf("%d%d",&n,&m)!=EOF)
    173     {
    174         ans=inf*-1;
    175         cas++;
    176         init();
    177         if (n==1 && m==1) 
    178         {
    179             printf("Case %d: %d
    ",cas,val[n][m]);
    180             init_a(1),init_a(0);
    181             continue;
    182         }
    183         work();
    184         printf("Case %d: %d
    ",cas,ans);
    185         init_a(1),init_a(0);
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    .linearDrag on rigidbody / rigidbody2D in code?
    Unity5权威讲解+项目源码+MP4
    C#的扩展方法解说
    use crunch compression
    IIS服务命令
    使用批处理打开控制面板中的功能
    一次性在一个文件夹里建立多个文件夹
    bat 批处理切换到当前脚本所在文件夹
    %date~0,4%和 %time~0,2%等用法详解(转)
    DOS批处理高级教程(还不错)(转)
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6535896.html
Copyright © 2011-2022 走看看