poj1185炮兵阵地

炮兵阵地
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 43084   Accepted: 16457

Description

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:

如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。

Input

第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。

Output

仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

Sample Input

5 4
PHPP
PPHH
PPPP
PHPP
PHHP

Sample Output

6

Source

也是状压dp入门题,代码没有,我重构了三遍,还是wa,心态爆炸了
无所谓了,能学到东西就好了
主要是学到了状压dp其实可以用三进制或者四,五进制,而且写起来不是特别麻烦的
然后是dfs的转移,还有一种提前打表的判断是否可行的方法,都是非常好的思路

 

还有这个判断相邻两格是否同时为1的方法,我觉得非常不错,而且方便好写
位运算还是要多学学啊

思路非常简单,就不说了。。
重构3遍。。写了我几乎一整天啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

 

————————————————————————————————更新于3天后
我tm在洛谷上发现了这题
然后重新交了一下,发现
我每一次重构都是没有必要的,因为,全是代码自身的逻辑错误和手残
我每一个思路都是对的,都能过

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

我在干什么
以下是我的两份的代码

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <string.h>
#define ll long long
using namespace std;
inline int read() {
    char c=getchar();int a=0,b=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int n,m,a[101][11],ans,much,f[101][60001],can[60001];//3µÄ10´Î·½ÊÇ59000+ 
bool in_s[60001];
int ask(int x,int i)//ÎÊ3½øÖÆÊýxµÄµÚiλÊÇɶ
{
    int c[13],tot=0;
    while(x>=3)
    {
        c[++tot]=x%3;
        x/=3;
    }
    c[++tot]=x;
    while(tot<m)
    {
        c[++tot]=0;
    }
    return c[tot-i+1];
}
void dfs(int x,int where,int now,int sat,int now_v)//µÚ¼¸ÅÅ£¬ÏÖÔÚµ½Á˵ڼ¸Î»£¬´ú±íÏÖÔÚµÄ״̬µÄÊý×ÖÊǶàÉÙ£¬ÉÏÒ»¸ö״̬£¬ÏÖÔڵļÛÖµÊǶàÉÙÁË 
{
//    cout<<x<<' '<<where<<endl;
    if(in_s[now])return ;//Èç¹ûÇ°Ã涼ÒѾ­²»Âú×ãÁË£¬ºóÃæ¿Ï¶¨Ò²²»Âú×ã 
    if(where==m+1)
    {
        f[x][now]=max(f[x][now],now_v);
//        if(x==3&&sat==46)cout<<now<<' '<<f[x][now]<<endl;
        if(x==n)ans=max(ans,f[x][now]);
        return ;
    }
    int no=ask(sat,where);
    if(no==2)//ÉÏÒ»ÐеÄÕâ¸öλÖÃÓÐÈË
    {
        dfs(x,where+1,now+pow(3,m-where),sat,now_v);//Ìî1 
    }
    else
    {
        if(no==1)
        {
            dfs(x,where+1,now,sat,now_v);//²»·Å
//            if(a[x][where]==0)
//            dfs(x,where+1,now+pow(3,m-where)*2,sat,now_v+1);//·ÅÒ»¸ö 
        }
        else
        {
            dfs(x,where+1,now,sat,now_v);//²»·Å
            if(a[x][where]==0)
            dfs(x,where+1,now+pow(3,m-where)*2,sat,now_v+1);//·ÅÒ»¸ö 
        }
    }
}
int main()
{
//    freopen(".in","r",stdin);
//    freopen(".out","w",stdout);
    n=read();m=read();
    much=pow(3,m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char c;
            cin>>c;
            if(c=='P')a[i][j]=0;
            else a[i][j]=1;
        }
    }
    for(int i=0;i<much;i++)
    {
        int cnt=3;
        for(int j=1;j<=m;j++)
        {
            if(ask(i,j)==2)
            {
                if(cnt<=2)
                {
//                    if(i==56)cout<<cnt<<' '<<j<<endl;
                    in_s[i]=1;
                    break;
                }
                cnt=1;
            }
            else
            {
                cnt++;
            }
        }
    }
//    cout<<in_s[56]<<endl;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<much;j++)
        {
            f[i][j]=-1000000;
        }
    }
    f[0][0]=0;
    dfs(1,1,0,0,0);
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<much;j++)
        {
            if(f[i][j]>=0)//Èç¹ûÕâ¸ö״̬´æÔÚ 
            {
                dfs(i+1,1,0,j,f[i][j]);//ÓÃdfsתÒÆ
//                cout<<f[i][j]<<' '<<i<<' '<<j<<endl;
            }
                
        }
    }
    cout<<ans<<endl;
    return 0;
}
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <map>
#include <string.h>
#define ll long long
using namespace std;
inline int read() {
    char c=getchar();int a=0,b=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int f[101][60][60],n,m,a[101][11],ins[1050],res[1050],tot;
int check(int x,int state)
{
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        if(((1<<(i-1))&state))cnt++;
        if(((1<<(m-i))&state)&&a[x][i]==1)return -1;
    }
    return cnt;
}
int main()
{
//    freopen(".in","r",stdin);
//    freopen(".out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char c;
            cin>>c;
            if(c=='P')a[i][j]=0;
            else a[i][j]=1;
        }
    }
    for(int i=0;i<(1<<m);i++)
    {
        if((i&(i<<1))||(i&(i<<2)))continue;
        ins[++tot]=i;
        res[ins[tot]]=tot;
//        cout<<i<<' '<<check(1,i)<<endl;
    }
//    cout<<endl;
    int ans=0,now=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=tot;j++)
        {
            int cnt=check(i,ins[j]);
            if(cnt!=-1)
            {
                for(int k=1;k<=tot;k++)//ÉÏÒ»ÅÅ 
                {
                    now=0;
                    if(check(i-1,ins[k])==-1)continue;
                    if((ins[j]&ins[k])==0)
                    {
                        f[i][j][k]=cnt;
                        for(int q=1;q<=tot;q++)//ÉÏÁ½ÅÅ 
                        {
                            if(i!=1)
                            {
                                if(check(i-2,ins[q])==-1)continue;
                                if((ins[q]&ins[j])==0)
                                {
                                    if(now<f[i-1][k][q])
                                    {
                                        now=f[i-1][k][q];
                                    }
//                                    now=max(now,f[i-1][ins[k]][ins[q]]);
                                }
                            }
                        }
                    }
                    f[i][j][k]+=now;
                    if(i==n)
                    {
                        ans=max(ans,f[i][j][k]);
                    }
                }
            }
        }
    }
//    cout<<check(6,4)<<endl;
//    cout<<f[6][4][9]<<endl;
    cout<<ans<<endl;
    return 0;
}

一个是用三进制的,一个是用二进制的。。
(dfs还是慢一些,没办法,没开O2)
都给我调对了。。。

posted @ 2023-11-02 14:58  HL_ZZP  阅读(5)  评论(0编辑  收藏  举报