【题目链接】
【算法】
状压DP
先搜出一行符合的情况,然后,f[i][j]表示第i行,状态为j,能够取得的最大值,DP即可
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 16 const int MAXS = 65536; int i,j,k,n,tot,ans,val,MASK; int a[MAXN][MAXN],f[MAXN][MAXS],ST[MAXS]; char c; int main() { while (scanf("%d",&a[1][1]) != EOF) { n = 1; tot = ans = 0; memset(f,0,sizeof(f)); scanf("%c",&c); while (c != ' ') { scanf("%d",&a[1][++n]); scanf("%c",&c); } for (i = 2; i <= n; i++) { for (j = 1; j <= n; j++) { scanf("%d",&a[i][j]); } } MASK = (1 << n) - 1; for (i = 0; i <= MASK; i++) { if (i & (i << 1)) continue; ST[++tot] = i; for (j = 0; j < n; j++) { if (i & (1 << j)) f[1][tot] += a[1][j+1]; } } for (i = 2; i <= n; i++) { for (j = 1; j <= tot; j++) { val = 0; for (k = 0; k < n; k++) { if (ST[j] & (1 << k)) val += a[i][k+1]; } for (k = 1; k <= tot; k++) { if (ST[j] & ST[k]) continue; if (ST[j] & (ST[k] >> 1)) continue; if (ST[j] & (ST[k] << 1)) continue; f[i][j] = max(f[i][j],f[i-1][k] + val); } } } for (i = 1; i <= n; i++) { for (j = 1; j <= tot; j++) { ans = max(ans,f[i][j]); } } printf("%d ",ans); scanf("%c",&c); } return 0; }