2019牛客暑期多校训练营(第二场)F
C(2*n,n)是4e7,总状态是4e7种,然后转移,o(n)直接从相邻的状态转移。和裸暴力没啥区别.
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long uLL; #define VNAME(value) (#value) #define bug printf("*********\n"); #define debug(x) cout<<"["<<VNAME(x)<<" = "<<(x)<<"]"<<endl; #define mid (l+r)/2 #define chl 2*k+1 #define chr 2*k+2 #define lson l,mid,chl #define rson mid+1,r,chr #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)); const long long mod=1e9+7; const int maxn=1e6+5; const int INF=0x7fffffff; const LL inf=0x3f3f3f3f; const double eps=1e-8; void f() { #ifndef ONLINE_JUDGE freopen("dat.in", "r", stdin); #endif // ONLINE_JUDGE } #ifndef ONLINE_JUDGE clock_t start=clock(); #endif // ONLINE_JUDGE int n,m; int mp[30][30]; LL sum,ans; int ar[15],br[15]; //a b 个表示一个集合 int la,lb; void dfs(int num) { //选n位 if(la>n||lb>n)return ; if(la==n&&lb==n) { //如果各选了 n 位就更新答案 ans=max(sum,ans); return ; } else { if(la<n) { LL tmp=0; for(int i=0; i<lb; i++) { //选到 a 集合 tmp+=mp[num][br[i]]; } sum+=tmp; ar[la++]=num; dfs(num+1); ar[--la]; sum-=tmp; } if(lb<n) { LL tmp=0; for(int i=0; i<la; i++) { //选到 b 集合 tmp+=mp[num][ar[i]]; } sum+=tmp; br[lb++]=num; dfs(num+1); br[lb--]; sum-=tmp; } } } int main() { f(); scanf("%d", &n); m = 2 * n; for(int i = 0; i < m; ++i) { for(int j = 0; j < m; ++j) { scanf("%d", &mp[i][j]); } } dfs(0); printf("%lld\n",ans); #ifndef ONLINE_JUDGE debug((1.0*(clock()-start)/1000)); #endif // ONLINE_JUDGE return 0; }