zoukankan      html  css  js  c++  java
  • hdu4796

    4月真是没写啥题,这题还是月初写的……

    不错的插头dp,首先由n和m的范围知肯定是轮廓线是横向划的

    问题的难点在于怎么处理下面两个问题

    1.怎么处理独立插头

    2.怎么处理完全将W和L左右隔开

    先说独立插头,一开始我是增加独立插头位来处理的,一直wa……

    后来意识到,因为独立插头一定是在第一行和最后一行唯一的,那么假定最顶部有m中状态,每种状态是一个位子上右下插头,最后一行类似处理,这样就解决了

    完全将W和L左右隔开比较简单,这要看当前如果是W,则这个格子左边的下插头一定是偶数个,是L则为奇数个,画个图即可理解。

    感觉自己插头dp的代码能力还是不足啊

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 const int mo=30007;
      6 const int maxl=2000010;
      7 char s[30];
      8 int n,m,ans,en,p,a[30][30],v[15],b[15],c[15];
      9 
     10 struct node{
     11     int p[mo],nex[maxl],len,f[maxl];
     12     ll st[maxl];
     13     void clr()
     14     {
     15         len=0; memset(p,255,sizeof(p));
     16     }
     17     void push(ll nw,int s)
     18     {
     19         int x=nw%mo;
     20         for (int i=p[x];i!=-1; i=nex[i])
     21             if (st[i]==nw)
     22             {
     23                 f[i]=min(f[i],s);
     24                 return;
     25             }
     26         st[++len]=nw; f[len]=s;
     27         nex[len]=p[x]; p[x]=len;
     28     }
     29 } h[2];
     30 
     31 void get(ll st)
     32 {
     33     for (int i=m; i>=0; i--)
     34     {
     35         c[i]=st&7;
     36         st>>=3;
     37     }
     38 }
     39 
     40 ll put()
     41 {
     42     memset(v,255,sizeof(v)); v[0]=0;
     43     ll st=0; int t=0;
     44     for (int i=0; i<=m; i++)
     45     {
     46         if (v[b[i]]==-1) v[b[i]]=++t;
     47         b[i]=v[b[i]];
     48         st<<=3; st|=b[i];
     49     }
     50     return st;
     51 }
     52 
     53 void shift()
     54 {
     55     for (int i=m;i; i--) b[i]=b[i-1];
     56     b[0]=0;
     57 }
     58 
     59 int check(int j)
     60 {
     61     int f=0;
     62     for (int i=0; i<=j; i++)
     63         f+=(c[i]>0);
     64     return f;
     65 }
     66 
     67 void dp(int i,int j)
     68 {
     69     for (int k=1; k<=h[p^1].len; k++)
     70     {
     71         ll st=h[p^1].st[k];
     72         get(st); int pw=h[p^1].f[k];
     73         int x=c[j-1],y=c[j];
     74         memcpy(b,c,sizeof(b));
     75         if (a[i][j]>=0)
     76         {
     77             if (x&&y)
     78             {
     79                 if (x==y) continue;
     80                 b[j-1]=b[j]=0;
     81                 for (int r=0; r<=m; r++)
     82                     if (b[r]==x) b[r]=y;
     83                 if (j==m) shift();
     84                 h[p].push(put(),pw+a[i][j]);
     85                 continue;
     86             }
     87             else if (x||y)
     88             {
     89                 int r=x+y;
     90                 if (a[i][j+1]>=0)
     91                 {
     92                     b[j]=r; b[j-1]=0;
     93                     h[p].push(put(),pw+a[i][j]);
     94                 }
     95                 if (a[i+1][j]>=0||(i==n&&!check(j-2)))
     96                 {
     97                     b[j]=0; b[j-1]=r;
     98                     if (j==m) shift();
     99                     h[p].push(put(),pw+a[i][j]);
    100                 }
    101             }
    102             else {
    103                 if (a[i][j+1]>=0&&(a[i+1][j]>=0||(i==n&&!check(j-2))))
    104                 {
    105                     b[j]=b[j-1]=m+1;
    106                     h[p].push(put(),pw+a[i][j]);
    107                 }
    108                 b[j]=b[j-1]=0;
    109                 if (j==m) shift();
    110                 h[p].push(put(),pw);
    111             }
    112         }
    113         else {
    114             if (a[i][j]==-1)
    115             {
    116                 if (j==m) shift();
    117                 h[p].push(put(),pw);
    118                 continue;
    119             }
    120             int sd=check(j-2);
    121             if (!(sd&1)&&a[i][j]==-3) continue;
    122             if (sd&1&&a[i][j]==-2) continue;
    123             if (j==m) shift();
    124             h[p].push(put(),pw);
    125         }
    126     }
    127 }
    128 
    129 int main()
    130 {
    131     //freopen("1.in","r",stdin);
    132     //freopen("1.out","w",stdout);
    133     while (scanf("%d%d",&n,&m)!=EOF)
    134     {
    135         memset(a,255,sizeof(a));
    136         for (int i=1; i<=n; i++)
    137         {
    138             scanf("%s",s+1);
    139             for (int j=1; j<=m; j++)
    140             {
    141                 int x=-1;
    142                 if (s[j]=='#') x=-1;
    143                 else if (s[j]=='W') x=-2;
    144                 else if (s[j]=='L') x=-3;
    145                 else x=s[j]-'0';
    146                 a[i][j]=x;
    147             }
    148         }
    149         ans=1e9+7;
    150         h[1].clr(); h[0].clr(); p=0;
    151         for (int i=1; i<=m; i++)
    152             if (a[1][i]>=0)
    153             {
    154                 memset(b,0,sizeof(b)); b[i]=1;
    155                 h[0].push(put(),0);
    156             }
    157         for (int i=1; i<=n; i++)
    158             for (int j=1; j<=m; j++)
    159             {
    160                 p^=1; h[p].clr();
    161                 dp(i,j);
    162               //  cout <<h[p].len<<" "<<i<<" "<<j<<endl;
    163             }
    164         for (int k=1; k<=h[p].len; k++)
    165         {
    166             get(h[p].st[k]);
    167             int sd=check(m);
    168             if (sd==1) ans=min(ans,h[p].f[k]);
    169         }
    170         if (ans==1000000007) puts("-1"); else printf("%d
    ",ans);
    171     }
    172 }
    View Code
  • 相关阅读:
    MySQL max_allowed_packet设置及问题
    centos 7 编译安装mysql 详细过程
    如何快速查看mysql数据文件存放路径?
    centos yum 库更新
    centos 7 ifconfig 命令找不到
    http协议
    前端那些事儿
    C++接口的定义与实现的详细过程
    List转为字符串
    spring cloud spring boot JPA 克隆对象修改属性后 无法正常的执行save方法进行保存或者更新
  • 原文地址:https://www.cnblogs.com/phile/p/6746224.html
Copyright © 2011-2022 走看看