状态压缩dp。
如果要把 第j个元素合并掉。可选择 a[i][j] (i:0—n-1); 选择之后第 j 行第 j 列就不能再被选择。(即指向j的边和j指向其他元素的边不能再用)。
#include <stdio.h> #include <string.h> #define Maxsize 12 #define FindMax(a,b) a>b?a:b int v[Maxsize][Maxsize]; int dp[1030]; int n; int ans; void dfs(int u,int s,int k,int t) { int i,next; if(k==t-1) { /* i=u; while(i>0) { printf("%d",i%2); i/=2; } printf("\n");*/ for(i=0;i<n;i++) { if(((u>>i)&1)==0) { next=u|(1<<i); int max=0; for(int j=0;j<n;j++) if(j!=i&&((u>>j)&1)==0) { max=FindMax(v[j][i],max); } dp[next]=FindMax(dp[u]+max,dp[next]); ans=FindMax(dp[next],ans); } } return; } for(i=s;i<n;i++) { if(((u>>i)&1)==0) { next=u|(1<<i); dfs(next,i+1,k+1,t); } } } int main() { int i,j; while(~scanf("%d",&n)) { for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&v[i][j]); ans=0; memset(dp,0,sizeof(dp)); for(i=1;i<n;i++) { dfs(0,0,0,i); } printf("%d\n",ans); } return 0; }