题目链接:http://acm.uestc.edu.cn/#/problem/show/1608
状态压缩,0代表已经取了这个人,1代表没有取,一开始全1状态,
复杂度约为:O(2^n*n*n)
#include <iostream> #include <cstring> #include <queue> #include <cmath> #include <cstdlib> using namespace std; int N,M,T; int A[22][22][22]; int dp[1<<22]; bool vis[1<<22]; int dfs(int x) { if(dp[x]!=-1)return dp[x]; int i,j,k; for(i=0;i<N-2;i++) { if(x&(1<<i))break; //找到一个可以放的位置(其实就是组) } for(int j=i+1;j<N-1;j++) { if(x&(1<<j)) for(int k=j+1;k<N;k++) if(x&(1<<k)) dp[x] = max(dp[x],dfs(x^(1<<i)^(1<<j)^(1<<k)) + A[i][j][k]);//从i+1往后找到合适的j和k 在前一个状态完成后才能取得当前最大值 } return dp[x]; } int main() { int a,b,c,d; while(~scanf("%d",&N)) { memset(dp,-1,sizeof(dp)); int M = N*(N-1)*(N-2); M/=6; for(int i=1;i<=M;i++) { scanf("%d%d%d%d",&a,&b,&c,&d); A[a-1][b-1][c-1]=d; } dp[0]=0;//最后全满的临界状态为0 cout<<dfs((1<<N)-1)<<endl; } return 0; }