题意:给你n*n个数,要你取不相邻的数,取得一个最大值。
状态压缩DP。。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int M=1<<20;
int num,n,Max;
int state[100000];//存所有的状态
int map[25][25];
int dp[2][100000];//循环数组
void init(){
for(int i=0;i<M;i++){
if(i&(i<<1)) continue;
state[num++]=i;
}
}
int judge(int i,int x){
int t=n-1;
int sum=0;
while(x){
if(x&1)
sum+=map[i][t];
x>>=1;
t--;
}
return sum;
}
void solve(){
int i,j,k;
for(j=0;state[j]<num;j++)
dp[0][j]=judge(0,state[j]);
for(i=1;i<n;i++){
for(j=0;state[j]<num;j++){//枚举所有状态
Max=-1;
for(k=0;state[k]<num;k++){//便利state[j]上面一行的所有状态
if(state[j]&state[k]) continue;
int x=dp[(i+1)&1][k];
if(x>Max) Max=x;
}
dp[i&1][j]=Max+judge(i,state[j]);
}
}
Max=-1;
i--;
for(j=0;state[j]<num;j++)
if(Max<dp[i&1][j]) Max=dp[i&1][j];
}
int main(){
int i,j;
init();
//freopen("1.txt","w",stdout);
//printf("%d\n",num);
while(~scanf("%d",&n)){
memset(dp,0,sizeof dp);
num=1<<n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&map[i][j]);
solve();
printf("%d\n",Max);
}
return 0;
}