Description
A sequence of 3 * n numbers Xi is given, which requires that three sequences of AI, Bi, and Ci with N length be constructed to meet the following conditions:
Each number of 1 to 3 * n appears once and only once in the three sequences;
S = sum (X [ai]-X [bi]) * X [CI]) is the largest.
The maximum output value is S. Multiple groups of data.
Input Format
The first line contains two numbers T and N, and T is the number of data groups. N is described as a question.
In the next T line, each line contains 3 * n numbers, indicating Xi.
Output Format
The output contains t rows, with the maximum output s for each row.
Sample Input
1 24 1 8 2 0 5
Sample output
46
Hint
No more than 1000 groups of data for 1 <= n <= 10;
For 11 <= n <= 15, no more than 100 groups of data;
For 16 <= n <= 20, there are no more than 10 groups of data;
For 21 <= n <= 25, there is only one group of data.
All xi <= 1000.
Solution
First, orz yff, how to think of DFS... The standard solution is like pressing DP or getting stuck, and I do not know where it is slower than the brute force.
1. When a> = C> = B (a-B) * C is the largest. Just push it out.
2. Sort the number of 3 * n read records in ascending order, X1 ~ XN must be in each group, and it must be B of each group.
3. Sort n tuples (AI, Bi, and CI) in ascending order of Ci. A1 <= a2 <= A3 <=... <= An, B1> = b2 >=…> = Bn. So b1 = xn, b2 = xn-1... BN = x1.
4. Optimum pruning: Two tuples (AI, Bi, CI) and (AJ, BJ, CJ) are the final answers.
(AI-Bi) * CI + (AJ-BJ) * CJ> (AI-Bi) * AJ + (CI-BJ) * CJ
That is, (CI-AJ) (AI-bi-CJ)> 0
Then let's talk about DFS =
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 int T,n,a[30],c[30],t[100],ans,now;bool vis[100]; 5 bool check(int x) 6 { 7 for(int i=1;i<x;i++) 8 { 9 if(c[i]>a[x]&&a[i]-t[3*n-i+1]<c[x])return 0;10 if(c[i]<a[x]&&a[i]-t[3*n-i+1]>c[x])return 0;11 }12 return 1;13 }14 void dfs(int xa,int tc)15 {16 if(xa==n+1)17 {18 if(ans<now)ans=now;19 return;20 }21 for(int i=xa;i<=2*n;i++)22 if(!vis[i])23 {24 vis[i]=1,a[xa]=t[i];25 for(int j=std::max(i,tc)+1;j<=2*n;j++)26 if(!vis[j])27 {28 vis[j]=1,c[xa]=t[j],29 now+=(a[xa]-t[3*n-xa+1])*c[xa];30 if(now*n>ans*xa&&check(xa))dfs(xa+1,j);31 now-=(a[xa]-t[3*n-xa+1])*c[xa],vis[j]=0;32 }33 vis[i]=0;break;34 }35 }36 bool cmp(int i,int j){return i>j;}37 int main()38 {39 for(scanf("%d%d",&T,&n);T;T--)40 {41 for(int i=1;i<=3*n;i++)scanf("%d",&t[i]);42 std::sort(t+1,t+1+3*n,cmp);ans=0;43 dfs(1,0);printf("%d\n",ans);44 }45 }View code