题意:中文题。

思路,经典的状态压缩题目。

由于列长比较小,我们可以以行为阶段用状态压缩来做。

由于攻击只占两个格,这样从行的角度看,第i行的炮兵只与前i-1和前i-2行有关系。这样如果用j,k,l分别表示第i,i-1,i-2行的炮兵摆放状态,而num[i][j]表示第i个摆放状态为j时的炮兵个数。dp[i][k][j]表示以i为最后一行,倒数第一行摆放为j,倒数第二行摆放为k时的最优解。

这样得到状态转移方程dp[i][k][j]=max{dp[i-1][l][k]+num[i][j]},前提是j和k、l都不互相攻击。

其中炮兵的摆放状态要预处理出来,如果m至大为10,这样枚举的话最多是2^10。由于最后得到合法状态不多,使用的时候可以直接用保存的下标而不是用二进制表示状态。这样可以大大提高时空复杂度。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
using namespace std;
vector<];
vector<];
][];
int m,n;
bool check(int sta,int d)
{
    <<d);
}
bool check1(int c,int sta)//检查是否在山上放炮
{
    ; i<m; ++i)
        if(grid[c][i]=='H'&&check(sta,i))
            return false;
    return true;
}
bool attack(int d,int sta)//某状态下判断同行之间是否相互攻击
{
    >=&&check(sta,d-)) return true;
    >=&&check(sta,d-)) return true;
    <m&&check(sta,d+)) return true;
    <m&&check(sta,d+)) return true;
    return false;
}
int check2(int sta)//判断是否互相攻击和统计炮个数
{
    ;
    ; i<m; ++i)
        if(check(sta,i))
        {
            ;
            else cnt++;
        }
    return cnt;
}
void init(int c)
{
    ; i<(<<m); ++i)
        if(check1(c,i))//没有放在山坡上的情况
        {
            int cnt=check2(i);//判断是否互相攻击和炮个数
            )
            {
                sta[c].push_back(i);//保存摆放位置状态
                num[c].push_back(cnt);//保存对应状态下的个数
            }
        }
}
][][];
bool attack2(int sta1,int sta2)//判断不同行之间的状态下炮是否互相攻击
{
    ; i<m; ++i)
        if(check(sta1,i)&&check(sta2,i)) return true;
    return false;
}
int main()
{
    scanf("%d%d",&n,&m);
    ; i<=n; ++i)
    {
        scanf("%s",grid[i]);
        init(i);
    }
    )
    {
        ;
        ;i<sta[].size();++i)
            ans=max(ans,num[][i]);
        printf("%d\n",ans);
        ;
    }
    ; i<sta[].size(); ++i)
        ; j<sta[].size(); ++j)
            ][i],sta[][j]))
                dp[][i][j]=num[][i]+num[][j];
    ; i<=n; ++i)
    {
        ; k<sta[i].size(); ++k)
            ; j<sta[i-].size(); ++j)
            {
                ][j];
                if(!attack2(stak,staj))
                {
                    ;
                    ; l<sta[i-].size(); ++l)
                    {
                        ][l];
                        if(!attack2(stak,stal)&&!attack2(staj,stal))
                            maxn=max(maxn,dp[i-][l][j]);
                    }
                    dp[i][j][k]=maxn+num[i][k];
                }
            }
    }
    ;
    ; i<sta[n].size(); ++i)
        ; j<sta[n-].size(); ++j)
            ans=max(ans,dp[n][j][i]);
    printf("%d\n",ans);
    ;
}

POJ 1185 炮兵阵地(经典的状态压缩DP)的更多相关文章

  1. POJ 1185 炮兵阵地 经典的 状态压缩dp

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16619   Accepted: 6325 Description ...

  2. POJ 1185 炮兵阵地(动态规划+状态压缩)

    炮兵阵地 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原( ...

  3. poj 1185 炮兵阵地 [经典状态压缩DP]

    题意:略. 思路:由于每个大炮射程为2,所以如果对每一行状态压缩的话,能对它造成影响的就是上面的两行. 这里用dp[row][state1][state2]表示第row行状态为state2,第row- ...

  4. poj -1185 炮兵阵地 (经典状压dp)

    http://poj.org/problem?id=1185 参考博客:http://poj.org/problem?id=1185 大神博客已经讲的很清楚了,注意存状态的时候是从1开始的,所以初始化 ...

  5. POJ 1185 炮兵阵地 状压dp

    题目链接: http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K 问题描述 司令部的将军们打算在N*M ...

  6. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  7. poj - 1185 炮兵阵地 状压DP 解题报告

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21553   Accepted: 8363 Description ...

  8. POJ 1185炮兵阵地 (状压DP)

    题目链接 POJ 1185 今天艾教留了一大堆线段树,表示做不动了,就补补前面的题.QAQ 这个题,我第一次写还是像前面HDU 2167那样写,发现这次影响第 i 行的还用i-2行那样,那以前的方法就 ...

  9. POJ - 1185 炮兵阵地 (插头dp)

    题目链接 明明是道状压dp的题我为啥非要用插头dp乱搞啊 逐行枚举,设dp[i][S]为枚举到第i个格子时,状态为S的情况.S为当前行上的“插头”状态,每两个二进制位表示一个格子,设当前格子为(x,y ...

随机推荐

  1. @ResponseStatus

    返回一个指定的http response状态码. @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "IOException oc ...

  2. Java Swing事件处理机制

    Java Swing的事件处理机制 Swing GUI启动后,Java虚拟机就启动三个线程,分别为主线程,事件派发线程(也是事件处理线程)和系统工具包线程. 主线程 :负责创建并显示该程序的初始界面: ...

  3. 20145218 《Java程序设计》第02次实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.12 实验名称:Java面向对象程序设计 一.实验内容 初步掌握单元测试和T ...

  4. 2.2 利用项目模板创建ASP.NET MVC项目

    1.启动VS2012,点击“文件|新建|项目”. 2.在新建项目的窗口中,选择ASP.NET MVC 4应用程序. 3.在新ASP.NET MVC 4项目窗口中的“选择模板”列表中选择“基本”模板,在 ...

  5. saiku-添加数据源以及保证数据源的一致性

    采用任何一种添加数据源的方式都不能保证数据源的一致和完整,所以需要两种结合来管理数据源 1.通过saiku的管理台添加数据源 ① 第一种方式:schema和ds都在管理台添加 1)上传schema文件 ...

  6. 关于 iOS 批量打包的总结

      关于 iOS 批量打包的总结 本文作者: 伯乐在线 - Tsui YuenHong .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 如果你曾经试过做多 target 的项目,到了测试人员要 ...

  7. android:launchMode的四种方式

    Activity一共有以下四种launchMode: standard singleTop singleTask singleInstance 1.standard standard模式是默认的启动模 ...

  8. Linux sed命令实例详解

    简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...

  9. sqlserver获取表名,字段名

    一.获取表的基本信息 SELECT [TableName] = [Tables].name , [TableOwner] = [Schemas].name , [TableCreateDate] = ...

  10. sqlserver 2008 存储过程调用存储过程或方法

    函数:拆分字符串,并返回一个table CREATE FUNCTION [dbo].[f_splitSTR](@s varchar(max), --待分拆的字符串@split varchar(10) ...