計蒜客習題:灌溉機器人
阿新 • • 發佈:2019-02-10
問題描述
農田灌溉是一項十分費體力的農活,特別是大型的農田。蒜頭君想為農民伯伯們減輕農作負擔,最近在研究一款高科技——灌溉機器人。它可以在遠端電腦控制下,給農田裡的作物進行灌溉。
現在有一片 N 行 M 列的農田。農田的土壤有兩種型別:型別 HH 和型別 PP,每一個格子上的土壤型別相同。其中型別 P 的土壤硬度較大,可以用來佈置灌溉機器人,但是一個格子上只能佈置一臺。型別 H 的土壤不能佈置灌溉機器人。一臺灌溉機器人的灌溉區域如下圖所示:
黃色表示灌溉機器人佈置的格子,紅色表示其灌溉區域,即四個方向上各外擴充套件兩個格子。
蒜頭君想在農田上儘可能多佈置一些灌溉機器人,但是任意一臺機器人不能在任意一臺機器人的灌溉區域裡,否則機器容易進水出故障。現在已知農田每個格子的土壤型別,請你來幫蒜頭君計算一下,蒜頭君最多能佈置多少臺灌溉機器人。
輸入格式
輸入第一行輸入兩個正整數N,M(N≤100,M≤10),表示農田的行和列。
接下來輸入 N 行,每行輸入連續的 M 個字元(P或者H),中間沒有空格。表示農田每個格子上的土壤型別。
輸出格式
輸出一行,輸出一個整數,表示最多能擺放的灌溉機器人的數量。
樣例輸入
3 4
PHPP
PHPP
PHHP
樣例輸出
3
AC程式碼
#include<stdio.h>
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;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%c",&c);
if(c=='P')map[i]+=1<<(m-j-1);
}
getchar();
}
t=1<<m;
j=0;
for(i=0;i<t;i++)
if(b2(i))tdp[j++]=i;
tn=j;
for(i=0;i<tn;i++)
{
for(j=0;j<tn;j++)
{
if (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;i<n;i++)
{
for(j=0;j<tn;j++)
if(b1(tdp[j],map[i]))
for(k=0;k<tn;k++)
if(b1(tdp[k],map[i-1])&&b3(tdp[j],tdp[k]))
for(l=0;l<tn;l++)
if(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;i<tn;i++)
for(j=0;j<tn;j++)
ans=max(ans,dp[n-1][i][j]);
printf("%d",ans);
}