ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

郑厂长系列故事——排兵布阵(HDU-4539)(状压DP)

2020-03-12 11:39:04  阅读:267  来源: 互联网

标签:排兵 HDU 4539 int 行第 士兵 sta 厂长 220


  郑厂长不是正厂长
  也不是副厂长
  他根本就不是厂长
  事实上
  他是带兵打仗的团长

  一天,郑厂长带着他的军队来到了一个n*m的平原准备布阵。
  根据以往的战斗经验,每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置。当然,一个士兵不能站在另外一个士兵所能攻击到的位置,同时因为地形的原因平原上也不是每一个位置都可以安排士兵。
  现在,已知n,m 以及平原阵地的具体地形,请你帮助郑厂长计算该阵地,最多能安排多少个士兵。

Input

输入包含多组测试数据;
每组数据的第一行包含2个整数n和m (n <= 100, m <= 10 ),之间用空格隔开;
接下来的n行,每行m个数,表示n*m的矩形阵地,其中1表示该位置可以安排士兵,0表示该地形不允许安排士兵。

Output

请为每组数据计算并输出最多能安排的士兵数量,每组数据输出一行。

Sample Input

6 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

Sample Output

2

 

题意:中文题,不过多叙述题意。

思路:这道题的话,题里所给出的曼哈顿距离为:两点在南北方向上的距离加上在东西方向上的距离,即d(i,j)=|xi-xj|+|yi-yj|

然后,我们继续考虑这道题,我们需要用状态压缩的解法来做,但是这里需要注意一点,我们不能两行之间进行状态压缩,因为第一行会影响到第三行(炮兵的打击范围可以看出),那么就只能两行两行的进行状态压缩。所以我们设dp[i][j][k]表示第i行第j个状态,第i-1行第k个状态下的最大士兵数。这样我们就可以进行状态压缩了。

AC代码:

#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int dp[110][220][220];//dp[i][j][k]表示第i行第j个状态,第i-1行第k个状态下的最大士兵数
int a[220][220];
int sta[220];
int n,m;
int judge(int i,int x)
{
    int sum=0;
    int j=m-1;
    while(x)
    {
        if(x&1)
            sum+=a[i][j];
        x>>=1;
        j--;
    }
    return sum;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int num=0;
        for(int i=0; i<(1<<m); i++)
        {
            if((i&(i>>2))==0 && (i&(i<<2))==0)
                sta[num++]=i;
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
                scanf("%d",&a[i][j]);
        }
        int ans=0;
        memset(dp,0,sizeof(dp));
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<num; j++)
            {
                for(int k=0; k<num; k++)
                {
                    if((sta[j]&(sta[k]>>1)) || (sta[j]&(sta[k]<<1)))
                        continue;
                    if(i==0)
                    {
                        dp[i][j][k]=judge(i,sta[j]);
                        ans=max(ans,dp[i][j][k]);
                        continue;
                    }
                    int cnt=0;
                    for(int x=0; x<num; x++)
                    {
                        if((sta[x]&(sta[k]>>1)) || (sta[x]&(sta[k]<<1)))
                            continue;
                        if(sta[j]&sta[x])
                            continue;
                        cnt=max(cnt,dp[i-1][k][x]);
                    }
                    dp[i][j][k]=cnt+judge(i,sta[j]);
                    ans=max(ans,dp[i][j][k]);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

标签:排兵,HDU,4539,int,行第,士兵,sta,厂长,220
来源: https://blog.csdn.net/weixin_43846139/article/details/104814650

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有