炮兵阵地(状态压缩DP)

本文介绍了一道编程题目,涉及C++实现的动态规划方法,解决炮兵阵地中炮台布局问题,考虑了地形限制和炮台之间的相互影响。通过滚动数组和状态转移计算最优解。
摘要由CSDN通过智能技术生成

 题目传送门:

292. 炮兵阵地 - AcWing题库

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int m,n;
int dp[2][1<<11][1<<11],f[110];//滚动数组dp[i][j][k],j为上一行的状态k为上两行的状态,f数组为储存每行的地形状态
int cnt[1<<11];//每一行的炮台树木
vector <int> state;//储存每一行的可行状态
bool chack(int x)//判断是否合法
{
    for(int i=0;i<m;i++)
        if((x>>i&1)&&((x>>i+1&1)||(x>>i+2&1)))
           return false;
    return true;
}
int cnts(int x)//储存每行的炮台个数
{
    int res=0;
    while(x)
    {
        res+=x&1;
        x>>=1;
    }
    return res;
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            char a;
            cin>>a;
            if(a=='H')
               f[i]+=1<<j;//储存每行地形状态
        }
    }
    for(int i=0;i<(1<<m);i++)
    {
        if(chack(i))
        {
            state.push_back(i);//储存可行方案
            cnt[i]=cnts(i);//计数
        }
    }
    //cout<<state.size()<<endl;
    for(int i=0;i<n+2;i++)
        for(int j=0;j<state.size();j++)//第i-2行的状态
           for(int u=0;u<state.size();u++)//第i-1行的状态
              for(int k=0;k<state.size();k++)//第i行的状态
                {
                    int a=state[u],b=state[j],c=state[k];
                    if((a&b)||(a&c)||(b&c))//范围内不能有其他炮台
                        continue;
                    if(f[i]&c) continue;//确定炮台一定在平原
                    dp[i&1][j][k]=max(dp[i&1][j][k],dp[(i-1)&1][u][j]+cnt[c]);//状态转移,本状态等于上一行的状态加本行的炮台数
                }
    cout<<dp[(n+1)&1][0][0]<<endl;//结果为所需行的下一行的不放任何炮台的数量
    return 0;
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值