题目链接:传送门
题面:
【题意】
给定2×n个人的相互竞争值,请把他们分到两个队伍里,如果是队友,那么竞争值为0,否则就为v[i][j]。
【题解】
爆搜,C(28,14)*28,其实可以稍加优化,因为分到两个队伍,所以第一个人肯定会分到一个队伍中,搜索可以有,C(27.13)*28,其实可以稍加剪枝,其实这个剪枝有点模糊,就是统计第i个人能产生的最大竞争值,当在过程中这个最大竞争值+当前值 < 暂存答案时,即为剪枝,【最优化剪枝】。
【代码】
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N = 30; 5 int a[N],b[N]; 6 int A,B,n; 7 ll v[N][N],ans; 8 void dfs(int pos,ll sum){ 9 if ( A > n || B > n ){ 10 return ; 11 } 12 if ( A == n && B == n ){ 13 ans = max(ans,sum); 14 return ; 15 } 16 if( A < n ){ 17 a[++A] = pos ; 18 for(int i=1;i<=B;i++){ 19 sum += v[pos][b[i]] ; 20 } 21 dfs( pos+1 , sum ); 22 for(int i=1;i<=B;i++){ 23 sum -= v[pos][b[i]]; 24 } 25 A--; 26 } 27 if( B < n ){ 28 b[++B] = pos ; 29 for(int i=1;i<=A;i++){ 30 sum += v[pos][a[i]] ; 31 } 32 dfs( pos+1 , sum ); 33 for(int i=1;i<=A;i++){ 34 sum -= v[pos][a[i]]; 35 } 36 B--; 37 } 38 } 39 int main() 40 { 41 scanf("%d",&n); 42 for(int i=1;i<=2*n;i++){ 43 for(int j=1;j<=2*n;j++){ 44 scanf("%lld",&v[i][j]); 45 } 46 } 47 dfs(1,0); 48 printf("%lld ",ans); 49 return 0; 50 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N = 30; 5 int a[N],b[N],A,B,n; 6 ll v[N][N],p[N],Maxn[N],sum[N]; 7 ll res , ans ; 8 void dfs(int pos ){ 9 if ( A == n && B == n ){ 10 res = max( res , ans ); 11 return ; 12 } 13 if( ans + sum[pos] < res ) //当前答案加上后缀 < 已存答案 14 return ; 15 if( A < n ){ 16 ll tmp = ans ; 17 a[++A] = pos ; 18 for(int i=1;i<=B;i++) 19 ans += v[pos][b[i]]; 20 dfs( pos+1 ) ; 21 A--; 22 ans = tmp ; 23 } 24 if( B < n ){ 25 ll tmp = ans ; 26 b[++B] = pos ; 27 for(int i=1;i<=A;i++) 28 ans += v[pos][a[i]]; 29 dfs( pos+1); 30 B--; 31 ans = tmp ; 32 } 33 } 34 int main() 35 { 36 scanf("%d",&n); 37 for(int i=1;i<=2*n;i++){ 38 for(int j=1;j<=2*n;j++){ 39 scanf("%lld",&v[i][j]); 40 } 41 } 42 for(int i=1;i<=2*n;i++){ 43 for(int j=1;j<=2*n;j++){ 44 p[j] = v[i][j]; 45 } 46 sort( p+1,p+1+2*n); 47 for(int j=n+1;j<=2*n;j++){ 48 Maxn[i] += p[j] ; 49 } 50 } 51 //预处理sum后缀和,可以在过程中加入进行剪枝 52 for(int i=2*n;i>=1;i--){ 53 sum[i] = sum[i+1] + Maxn[i] ; 54 } 55 A = 1 ; 56 a[1] = 1 ; 57 dfs(2); 58 printf("%lld ",res); 59 return 0; 60 }