题目链接:http://poj.org/problem?id=1185

#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAXX=61; int map[105]; int st[MAXX]; int cnt[MAXX]; int dp[105][MAXX][MAXX]; int ss; int max(int a,int b) { return a>b?a:b; } bool IsCan(int a){ if(a&(a<<1))return false; if(a&(a<<2))return false; return true; } int Sum(int a){// 通过移位求x中一的个数,也就是这行中大炮的个数 int b=0; while(a>0){ if(a&1)b++; a>>=1; } return b; } void GetState(int n)// 求出所有可能的状态。 { int limit=1<<n; for(int i=0;i<limit;i++) { if(IsCan(i)) { st[ss]=i; cnt[ss++]=Sum(i); } } } int main() { int row,col,i,j,k,r; char ch; scanf("%d%d",&row,&col); ss=0; GetState(col);//printf("%d\n",cnt);可在这里输出一下总共有多少种状态,输出为60种 memset(dp,-1,sizeof(dp)); getchar(); for(i=0;i<row;i++) { for(j=0;j<col;j++) { ch=getchar(); if(ch=='H')map[i] |= (1<<j); } getchar(); } for(i=0;i<ss;i++) { if(!(st[i]&map[0])){ dp[0][0][i]=cnt[i]; } } for(r=1;r<row;r++){ for(i=0;i<ss;i++){//r 行状态枚举 if(st[i]&map[r])continue; for(j=0;j<ss;j++){ //r-1 行状态枚举 if(st[i]&st[j])continue; for(k=0;k<ss;k++){//r-2行状态枚举 if(st[i]&st[k])continue; if(dp[r-1][k][j]==-1)continue; dp[r][j][i]=max(dp[r][j][i],dp[r-1][k][j]+cnt[i]); } } } } int big=-2; for(i=0;i<ss;i++){ for(j=0;j<ss;j++){ if(big<dp[row-1][i][j]){ big=dp[row-1][i][j]; } } } printf("%d\n",big); return 0; }

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐