zoukankan      html  css  js  c++  java
  • POJ3133 Manhattan Wiring 插头DP

      题目链接:http://poj.org/problem?id=3133

      用两条线段分别连接2-2和3-3,使得他们长度的总和最小。

      典型的插头DP题目,用0,2,3,种状态来表示每个格子的插头分别是没有插头,2号插头,3号插头,然后把所有可能的转移情况列出来,只是情况比较多,而且一定要考虑仔细,不然检查代码会很惨的。。话说A完这道题后感觉真爽啊O(∩_∩)O~

      1 //STATUS:C++_AC_360MS_900KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 #define LL long long
     15 #define pii pair<int,int>
     16 #define Max(a,b) ((a)>(b)?(a):(b))
     17 #define Min(a,b) ((a)<(b)?(a):(b))
     18 #define mem(a,b) memset(a,b,sizeof(a))
     19 #define lson l,mid,rt<<1
     20 #define rson mid+1,r,rt<<1|1
     21 const int N=10,INF=0x3f3f3f3f,MOD=60007,STA=1000010;
     22 const LL LNF=0x3f3f3f3f3f3f3f3f;
     23 const double DNF=100000000000;
     24 
     25 int g[N][N];
     26 int n,m;
     27 
     28 struct Hash{
     29     int first[MOD],next[STA],size;
     30     int f[STA],sta[STA];
     31     void init(){
     32         size=0;
     33         mem(first,-1);
     34     }
     35     void add(int st,int ans){
     36         int i,u=st%MOD;
     37         for(i=first[u];i!=-1;i=next[i]){
     38             if(sta[i]==st){
     39                 f[i]=Min(f[i],ans);
     40                 return;
     41             }
     42         }
     43         f[size]=ans;
     44         sta[size]=st;
     45         next[size]=first[u];
     46         first[u]=size++;
     47     }
     48 }hs[2];
     49 
     50 void shift(int p)
     51 {
     52     int i,flag=(1<<((m+1)<<1))-1;
     53     for(i=0;i<hs[!p].size;i++){
     54         hs[p].add((hs[!p].sta[i]<<2)&flag,hs[!p].f[i]);
     55     }
     56 }
     57 
     58 int slove()
     59 {
     60     int i,j,k,x,y,left,up,p,sta,f;
     61     hs[0].init();
     62     hs[0].add(0,0);
     63     hs[p=1].init();
     64     for(i=0;i<n;i++){
     65         for(j=0;j<m;j++,hs[p=!p].init()){
     66             for(k=0;k<hs[!p].size;k++){
     67                 sta=hs[!p].sta[k];
     68                 f=hs[!p].f[k]+1;
     69                 x=(3<<(j<<1))&sta;
     70                 y=(3<<((j+1)<<1))&sta;
     71                 left=x>>(j<<1);
     72                 up=y>>((j+1)<<1);
     73                 if(g[i][j]){
     74                     if(g[i][j]==2){  //独立插头
     75                         if(left==2 && up==0){
     76                             hs[p].add(sta^x,f);
     77                         }
     78                         else if(left==0 && up==2){
     79                             hs[p].add(sta^y,f);
     80                         }
     81                         else if(left==0 && up==0){
     82                             if(g[i+1][j]==1 || g[i+1][j]==2)hs[p].add(sta|(2<<(j<<1)),f);
     83                             if(g[i][j+1]==1 || g[i][j+1]==2)hs[p].add(sta|(2<<((j+1)<<1)),f);
     84                         }
     85                     }
     86                     else if(g[i][j]==3){  //独立插头
     87                         if(left==3 && up==0){
     88                             hs[p].add(sta^x,f);
     89                         }
     90                         else if(left==0 && up==3){
     91                             hs[p].add(sta^y,f);
     92                         }
     93                         else if(left==0 && up==0){
     94                             if(g[i+1][j]==1 || g[i+1][j]==3)hs[p].add(sta|(3<<(j<<1)),f);
     95                             if(g[i][j+1]==1 || g[i][j+1]==3)hs[p].add(sta|(3<<((j+1)<<1)),f);
     96                         }
     97                     }
     98                     else {  //g[i][j]==1
     99                         if(left==up && left){
    100                             hs[p].add(sta^x^y,f);
    101                         }
    102                         else if((left==2 && up==0) || (left==0 && up==2)){
    103                             if(g[i+1][j])hs[p].add(sta^y|(2<<(j<<1)),f);
    104                             if(g[i][j+1])hs[p].add(sta^x|(2<<((j+1)<<1)),f);
    105                         }
    106                         else if((left==3 && up==0) || (left==0 && up==3)){
    107                             if(g[i+1][j])hs[p].add(sta^y|(3<<(j<<1)),f);
    108                             if(g[i][j+1])hs[p].add(sta^x|(3<<((j+1)<<1)),f);
    109                         }
    110                         else if(left==0 && up==0){   //这里一定要考虑仔细
    111                             if(g[i+1][j] && g[i][j+1]){
    112                                 hs[p].add(sta|(2<<(j<<1))|(2<<((j+1)<<1)),f);
    113                                 hs[p].add(sta|(3<<(j<<1))|(3<<((j+1)<<1)),f);
    114                             }
    115                             hs[p].add(sta,f-1);
    116                         }
    117                     }
    118                 }
    119                 else if(left==0 && up==0){
    120                     hs[p].add(sta,f-1);
    121                 }
    122             }
    123         }
    124         shift(p);
    125         hs[p=!p].init();
    126     }
    127     p=!p;
    128     for(i=0;i<hs[p].size;i++){
    129         if(hs[p].sta[i]==0)return hs[p].f[i]-2;
    130     }
    131     return 0;
    132 }
    133 
    134 int main()
    135 {
    136  //   freopen("in.txt","r",stdin);
    137     int i,j,ans;
    138     while(~scanf("%d%d",&n,&m) && (n || m))
    139     {
    140         mem(g,0);
    141         for(i=0;i<n;i++){
    142             for(j=0;j<m;j++){
    143                 scanf("%d",&g[i][j]);
    144                 if(g[i][j]==0)g[i][j]=1;
    145                 else if(g[i][j]==1)g[i][j]=0;
    146             }
    147         }
    148 
    149         ans=slove();
    150 
    151         printf("%d\n",ans);
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/zhsl/p/2997700.html
Copyright © 2011-2022 走看看