poj 1185

http://poj.org/problem?id=1185

View Code
/*
Problem: 1185 User: ruan123
Memory: 2128K Time: 266MS
Language: G++ Result: Accepted
说下dp方程:dp[i][j][k] 为第i行状态为Sj,第i-1行状态为Sk时前i行最多能放置的炮数。
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int dp[105][65][65];
int s[105],map[105],cnt,c[100];

void init(int m)
{
m = 1<<m;
for(int i = 0; i < m; ++ i){
if(!(i&(i<<1)) && !(i&(i<<2))){
int sum = 0;
int k = i;
while(k){ sum += k&1; k /= 2; }
c[cnt] = sum;
s[cnt++] = i;
}
}
}

int main()
{
int n,m,ans = 0;
char str[100];
cnt = 0;

scanf("%d%d",&n,&m);
for(int i = 0; i < n; ++ i){
scanf("%s",str);
for(int j = 0; str[j]; ++j )
if(str[j] == 'H') map[i] += (1 << j);
}

init(m);
memset(dp,-1,sizeof(dp));
for(int i = 0; i < cnt; ++ i)
if(!(map[0]&s[i])) dp[0][i][0] = c[i];

for(int i = 1; i < n; ++ i){
for(int j = 0; j < cnt; ++ j){
if(s[j]&map[i])continue;//有冲突
for(int k = 0; k < cnt; ++ k){
if(s[j]&s[k])continue;//有冲突
for(int l = 0; l < cnt; ++ l){
if(s[j]&s[l])continue;//有冲突
if(dp[i-1][k][l]<0)continue;//没有值
dp[i][j][k] = dp[i][j][k] > dp[i-1][k][l] + c[j] ? dp[i][j][k] : dp[i-1][k][l] + c[j];
}
}
}
}

for(int i = 0; i < cnt; ++ i)
for(int j = 0; j < cnt; ++ j){
ans = dp[n-1][i][j] > ans? dp[n-1][i][j] : ans;
}
printf("%d\n",ans);
return 0;
}



posted on 2012-04-05 21:37  aigoruan  阅读(145)  评论(0)    收藏  举报

导航