计蒜客习题:灌溉机器人


问题描述

农田灌溉是一项十分费体力的农活,特别是大型的农田。蒜头君想为农民伯伯们减轻农作负担,最近在研究一款高科技——灌溉机器人。它可以在远程电脑控制下,给农田里的作物进行灌溉。
现在有一片 N 行 M 列的农田。农田的土壤有两种类型:类型 HH 和类型 PP,每一个格子上的土壤类型相同。其中类型 P 的土壤硬度较大,可以用来布置灌溉机器人,但是一个格子上只能布置一台。类型 H 的土壤不能布置灌溉机器人。一台灌溉机器人的灌溉区域如下图所示:
计蒜客习题:灌溉机器人_第1张图片
黄色表示灌溉机器人布置的格子,红色表示其灌溉区域,即四个方向上各外扩展两个格子。
蒜头君想在农田上尽可能多布置一些灌溉机器人,但是任意一台机器人不能在任意一台机器人的灌溉区域里,否则机器容易进水出故障。现在已知农田每个格子的土壤类型,请你来帮蒜头君计算一下,蒜头君最多能布置多少台灌溉机器人。
输入格式
输入第一行输入两个正整数N,M(N≤100,M≤10),表示农田的行和列。
接下来输入 N 行,每行输入连续的 M 个字符(P或者H),中间没有空格。表示农田每个格子上的土壤类型。
输出格式
输出一行,输出一个整数,表示最多能摆放的灌溉机器人的数量。
样例输入
3 4
PHPP
PHPP
PHHP
样例输出
3


AC代码

#include
int dp[110][60][60];
int tdp[60];
int map[100];
int n,m,t,g1,g2=1;
int b1(int x,int y)//地图
{
    return (x|y)==y;
}
int b2(int x)//行内
{
    return !((x&(x>>1))||(x&(x>>2)));
}
int b3(int x,int y)//两行
{
    return !(x&y);
}
int count(int x)
{
    int a=0;

    while(x)
    {
        a+=x&1;
        x>>=1;
    }
    return a;
}
int max(int a,int b)
{
    return a>b?a:b;
}
int main()
{

    int i,j,k,l,tn,ans=0;
    char c;
    scanf("%d %d",&n,&m);
    fflush(stdin);
    getchar();
    for(i=0;ifor(j=0;jscanf("%c",&c);
            if(c=='P')map[i]+=1<<(m-j-1);
        }
        getchar();
    }
    t=1<0;
    for(i=0;iif(b2(i))tdp[j++]=i;
    tn=j;
    for(i=0;ifor(j=0;jif (b1(tdp[i], map[0]) && b1(tdp[j], map[1]))
                dp[1][i][j]=b3(tdp[i],tdp[j])?count(tdp[j])+count(tdp[i]):0;
        }

    }
    for(i=2;ifor(j=0;jif(b1(tdp[j],map[i]))
                for(k=0;kif(b1(tdp[k],map[i-1])&&b3(tdp[j],tdp[k]))
                        for(l=0;lif(b1(tdp[l],map[i-2])&&b3(tdp[j],tdp[l])&&b3(tdp[l],tdp[k]))
                                dp[i][k][j]=max(dp[i][k][j],dp[i-1][l][k]+count(tdp[j]));
    }
    for(i=0;ifor(j=0;j1][i][j]);
    printf("%d",ans);
}

你可能感兴趣的:(#,动态规划,算法竞赛刷题,计蒜客NOIP习题)