http://acm.hdu.edu.cn/showproblem.php?pid=2167
和POJ 1185炮兵阵地类似, 做法也类似,这里不再详细叙述。有一点需要注意就是要注意输入的格式,很蛋疼。。
代码:
#include<stdio.h>
#include<string.h>
#define MAX(a,b) (a) > (b) ? (a) : (b)
int N ;
int num[16][16] ;
char ch[1010] ;
int total;
int dp[2][1<<15] , pre, now ,row;
unsigned int S ;
void dfs(int pos , int s1 , int s2 , int sum){
if(pos == N+1){
if(dp[now][s2] == -1){
dp[now][s2] = dp[pre][s1] + sum ;
}
else{
dp[now][s2] = MAX(dp[now][s2] , dp[pre][s1] + sum);
}
return ;
}
dfs(pos+1,s1,(s2<<1) ,sum) ;
if(pos==1 && (s1&(1<<(N-pos)))==0 && (s1&(1<<(N-pos-1)))==0){
dfs(pos+2,s1,((s2<<1)+1)<<1,sum+num[row][pos] );
}
else if(pos==N && (s1&(1<<(N-pos)))==0 && (s1&(1<<(N-pos+1)))==0){
dfs(pos+1,s1,(s2<<1)+1,sum+num[row][pos]);
}
else if(pos>1 && pos<N && (s1&(1<<(N-pos)))==0 && (s1&(1<<(N-pos-1)))==0 && (s1&(1<<(N-pos+1)))==0){
dfs(pos+2,s1,((s2<<1)+1)<<1 ,sum+num[row][pos]);
}
}
void DP(){
pre = 0 ; now = 1 ;
memset(dp , -1 , sizeof(dp));
dp[now][0] = 0 ;
S = (1<<N) - 1 ;
for(row=1;row<=N;row++){
now = 1 - now ; pre = 1 - pre;
for(int j=0;j<=S;j++){
if(dp[pre][j] == -1) continue ;
dfs(1,j,0,0);
}
}
int ans= 0 ;
for(int j=0;j<=S;j++)
ans = MAX(ans , dp[now][j]);
printf("%d\n",ans);
}
int main(){
int len ;
while(gets(ch) != NULL){
int i , j ;
i = 0 ;
do{
if(ch[0] == 0) break ;
int len = strlen(ch);
j = 0 ; i++ ;
for(int c=0;c<len;c++){
if(ch[c] == ' ') continue ;
j++ ;
num[i][j] = 10*(ch[c]-'0') + ch[c+1]-'0' ;
c++ ;
}
}while(gets(ch)!=NULL) ;
N = i ;
DP();
}
return 0 ;
}