zoukankan      html  css  js  c++  java
  • [2013腾讯马拉松复赛第二场] HDU 4539 郑厂长系列故事——排兵布阵

    以后做比赛前一定补好睡眠,没有精神A不动题目……,最后一题的题意到2H才发现看错了,原来是要求曼哈顿距离等于2的而不是小于等于2的……,调了半天样例都输出1……。最后只AC了2题,第一个和最后一个,第二个怎么想怎么是爆搜,是不是爆搜?

    最后一题排兵布阵是比较经典的状压DP,看群里还有用点独立集做的,还有用插头DP做的?ORZ。

    做法跟POJ 1185炮兵阵地,这道经典状压DP神似,连题目都神似。所以具体转移方程也基本一样,需要枚举前两行的状态。具体细节不明白的可以先去搜poj 1185的解题报告。

    题目虽然给的时间很多,但是比赛怕超时就先预处理了所有当前行可行的状态。判断当前行k,和k-2行是否兼容跟炮兵阵地的处理方式一样,直接相与。处理k跟k-1行略有不同,是把k-1行的状态搓一个位(其实就是乘2,除2)相与,看这两个结果有没有不等于0的。其他都跟炮兵一样。

    View Code
      1 #include <set>
      2 #include <list>
      3 #include <queue>
      4 #include <stack>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <vector>
      8 #include <bitset>
      9 #include <cstdio>
     10 #include <string>
     11 #include <numeric>
     12 #include <cstring>
     13 #include <cstdlib>
     14 #include <iostream>
     15 #include <algorithm>
     16 #include <functional>
     17 using namespace std;
     18 typedef long long ll;
     19 #define Exp 1e-8
     20 #define inf 0x7fffffff
     21 #define read freopen("in.txt","r",stdin)
     22 #define write freopen("out.txt","w",stdout)
     23 #define maxn 200
     24 int n,m,top;
     25 int map[105][12],con[maxn][maxn],con2[maxn][maxn];
     26 int state[maxn][2],vm[105],dp[105][maxn][maxn];
     27 int max(int a,int b)
     28 {
     29     if(a>b)return a;
     30     return b;
     31 }
     32 void prt(int i)
     33 {
     34     int t=i;while(t)printf("%d",t%2),t>>=1;puts("");
     35 }
     36 bool check(int a,int b)//判断当前行的状态能否放入地图中
     37 {
     38     if(((~b)&a))return false;
     39     return true;
     40 }
     41 void init()//预处理一行能够放士兵的状态
     42 {
     43     int i,j;
     44     memset(state,0,sizeof(state));
     45     top=0;
     46     for(i=0;i<(1<<10)-1;++i)
     47     {
     48         if((i&(i<<2)))continue;
     49         state[top][0]=i;//0存放状态,1统计个数
     50         for(j=i;j;j-=j&(-j))state[top][1]++;
     51         ++top;//prt(state[top-1][0]);
     52     }
     53     for(i=0;i<top;++i)for(j=0;j<top;++j)//con[i][j]表示当前行跟上一行状态为i,j是否能共存
     54         con[i][j]=!(state[i][0]&state[j][0]);
     55     for(i=0;i<top;++i)for(j=0;j<top;++j)//con[i][j]表示当前行跟上二行状态为i,j是否能共存
     56     {
     57         int t1=state[i][0]&(state[j][0]<<1);
     58         int t2=state[i][0]&(state[j][0]>>1);
     59         con2[i][j]=!(t1|t2);
     60     }
     61 }
     62 int main()
     63 {
     64     //read;
     65     init();
     66     int i,j,k,s;
     67     while(~scanf("%d%d",&n,&m))
     68     {
     69         memset(vm,0,sizeof(vm));
     70         memset(map,0,sizeof(map));
     71         memset(dp,0,sizeof(dp));
     72         for(i=0;i<n;++i)
     73         {
     74             for(j=0;j<m;++j)
     75             {
     76                 scanf("%d",&map[i][j]);
     77                 vm[i]=(vm[i]+map[i][j])<<1;
     78             }
     79             vm[i]>>=1;//地图信息状态压缩
     80         }
     81         for(i=0;i<top;++i)
     82         {
     83             if(check(state[i][0],vm[0])==0)continue;
     84             for(j=0;j<top;j++)dp[0][i][j]=state[i][1];
     85         }
     86         for(i=0;i<top;++i)
     87         {
     88             if(check(state[i][0],vm[1])==0)continue;
     89             for(j=0;j<top;j++)
     90             {
     91                 if(check(state[j][0],vm[0])==0)continue;
     92                 if(con2[i][j]==0)continue;
     93                 dp[1][i][j]=max(dp[1][i][j],dp[0][j][0]+state[i][1]);
     94             }
     95         }
     96         for(s=2;s<n;++s)
     97             for(i=0;i<top;++i)
     98             {
     99                 if(check(state[i][0],vm[s])==0)continue;
    100                 for(j=0;j<top;++j)
    101                 {
    102                     if(check(state[j][0],vm[s-1])==0)continue;
    103                     if(con2[i][j]==0)continue;
    104                     for(k=0;k<top;++k)
    105                     {
    106                         if(check(state[k][0],vm[s-2])==0)continue;
    107                         if(con2[j][k]==0||con[i][k]==0)continue;
    108                         dp[s][i][j]=max(dp[s][i][j],state[i][1]+dp[s-1][j][k]);
    109                     }
    110                 }
    111             }
    112         int ans=0;
    113         for(i=0;i<top;++i)for(j=0;j<top;++j)ans=max(ans,dp[n-1][i][j]) ;
    114         printf("%d\n",ans);
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    Mina、Netty、Twisted一起学(七):公布/订阅(Publish/Subscribe)
    MySQL高可用之——keepalived+互为主从
    JS之BOM
    Mac下利用(xcode)安装git
    计算矩阵边缘元素之和
    什么是猴子补丁(monkey patch)
    协议支撑
    BZOJ 3727 PA2014 Final Zadanie 树形DP
    Linux cat命令
    iOS8新特性
  • 原文地址:https://www.cnblogs.com/mcflurry/p/2991018.html
Copyright © 2011-2022 走看看