首页 > 其他分享 >POJ 1185 炮兵阵地

POJ 1185 炮兵阵地

时间:2023-01-27 18:45:11浏览次数:51  
标签:int 1185 炮兵阵地 POJ 65 ans include dp 110

感觉上很难,确实自己做一开始没有想到是dp问题,同时没有进行剪枝,同时有一些准备工作没有做好

  • 没有提前将每一行的信息转成数字信息(做题经验不足)
  • 没有提前把每行可能的情况抽取出来
  • 没有想到其实确实是一个dp问题(其实一开始的贪心思路有些不太对)

判断贪心和dp问题的一个方法可以是看数据范围

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[105][65][65];
int cnt=0;
int str[65];
int sum[65];
int map[110];
char s[110][110];
bool check(int x)//判断这个排列是否为普通的合法序列
{
    if(x&(x<<1)) return false;
    if(x&(x<<2)) return false;
    return true;
}
int getSum(int x)//当前状态的炮兵数目
{
    int ans=0;
    while(x>0)
    {
        if(x&1) ans++;
        x>>=1;
    }
    return ans;
}
void before_hand(int mid)//预处理出所有的可能合法炮兵状态,cnt统计状态数
{
    for(int i=0;i<(1<<mid);i++)
    {
        if(check(i))
        {
            str[cnt]=i;//str数组记录状态,dp中的j和k都是str数组的下标
            sum[cnt]=getSum(i);
            cnt++;
        }
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(dp,-1,sizeof dp);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            char a;
            cin >> a;
            if(a=='H') map[i]|=(1<<j);//统计每一行的不合法格子状态
        }
    }
    before_hand(m);//其实可以不传参
    for(int i=0;i<cnt;i++)
    {
        if(!(str[i]&map[0])) dp[0][0][i]=sum[i];//先处理出第一行的情况
    }
    for(int r=1;r<n;r++)//枚举行数
    {
        for(int i=0;i<cnt;i++)//枚举当前行的排列
        {
            if(str[i]&map[r]) continue;
            for(int j=0;j<cnt;j++)//枚举上一行的排列情况
            {
                if(str[i]&str[j]) continue;
                for(int k=0;k<cnt;k++)//枚举i-2行的排列情况
                {
                    if(str[i]&str[k]) continue;
                    if(dp[r-1][k][j]==-1) continue;
                    dp[r][j][i]=max(dp[r][j][i],dp[r-1][k][j]+sum[i]);//更新即可
                }
            }
        }
    }
    int ans=0;//统计答案
    for(int i=0;i<cnt;i++)
    {
        for(int j=0;j<cnt;j++)
        {
            ans=max(ans,dp[n-1][i][j]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

标签:int,1185,炮兵阵地,POJ,65,ans,include,dp,110
From: https://www.cnblogs.com/ymx10086/p/17069156.html

相关文章

  • POJ--3255 Roadblocks(最短路)
    记录0:252023-1-27http://poj.org/problem?id=3255reference:《挑战程序设计竞赛(第2版)》2.4.4p108DescriptionBessiehasmovedtoasmallfarmandsometimese......
  • POJ--1182 食物链(并查集)
    记录15:392023-1-26http://poj.org/problem?id=1182reference:《挑战程序设计竞赛(第2版)》2.4.4p88Description动物王国中有三类动物A,B,C,这三类动物的食物链构成......
  • POJ--3253 Fence Repair(贪心/优先队列)
    记录23:572023-1-25http://poj.org/problem?id=3253reference:《挑战程序设计竞赛(第2版)》2.2.4p47DescriptionFarmerJohnwantstorepairasmalllengthofth......
  • POJ--2431 Expedition(优先队列)
    记录0:172023-1-26http://poj.org/problem?id=2431reference:《挑战程序设计竞赛(第2版)》2.2.4p77DescriptionAgroupofcowsgrabbedatruckandventuredona......
  • POJ1002 487-3279
    描述商人们喜欢使用方便记忆的电话号码。让号码方便记忆的一种方法是让它拼成好记的单词或词组。例如,你可以叫Waterloo大学TUT-GLOP。有时候只有数字的一部分参与拼写。当......
  • POJ--3069 Saruman's Army(贪心)
    记录0:332023-1-24http://poj.org/problem?id=3069reference:《挑战程序设计竞赛(第2版)》2.2.4p45DescriptionSarumantheWhitemustleadhisarmyalongastra......
  • POJ--2386 Lake Counting(DFS)
    记录0:332023-1-24http://poj.org/problem?id=3617reference:《挑战程序设计竞赛(第2版)》2.2.3p43DescriptionFJisabouttotakehisN(1≤N≤2,000)cows......
  • PIPOJ 最大连续子序列
    题目描述给定 K 个整数的序列{ N1, N2, ..., NK} ,其任意连续子序列可表示为{ Ni, Ni+1,...,Nj} ,其中1<=i<=j <=K。最大连续子序列是所有连续子序列......
  • PIPOJ 破译密码
    题目描述据说最早的密码来自于罗马的凯撒大帝。消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A 都分别替换成字......
  • 关于POJO
    pojo指简单的Java对象是实体类Entity和值对象VO还有DTO数据传输对象的统称Entity实体类,通常和对应的表字段的数量是一致的DTO数据传输对象,当客户端给服务器传递参......