1. 程式人生 > >計蒜客習題:灌溉機器人

計蒜客習題:灌溉機器人

問題描述

農田灌溉是一項十分費體力的農活,特別是大型的農田。蒜頭君想為農民伯伯們減輕農作負擔,最近在研究一款高科技——灌溉機器人。它可以在遠端電腦控制下,給農田裡的作物進行灌溉。
現在有一片 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); }