SGU 485 Arrays
485. Arrays
Time limit per test: 1.75 second(s)
Memory limit: 262144 kilobytes
Memory limit: 262144 kilobytes
input: standard
output: standard
output: standard
You are given a sequence of 3· N integers (X1, X2, ·s, X3· N). Create three sequences (A1, A2, ·s, AN), (B1, B2, ·s, BN) and (C1, C2, ·s, CN) such that:
- each of the integers from 1 to 3· N belongs to exactly one of the sequences A, B or C;
- the value of is the largest possible.
Input
Constraints on N | Constraints on T |
---|---|
1 ≤ N ≤ 10 | 1 ≤ T ≤ 1000 |
11 ≤ N ≤ 15 | 1 ≤ T ≤ 100 |
16 ≤ N ≤ 20 | 1 ≤ T ≤ 10 |
21 ≤ N ≤ 25 | T = 1 |
The input file contains T test cases, all having the same value of N. The first line of the input file contains the integers T and N, constrained as shown in the adjacent table. Each of the following T lines describes one test case and contains 3· N integers, the members of the sequence X. All these values are in the range from 0 to 1000.
Output
The output file should consist of T lines. Each line should contain the largest possible value of S for the corresponding test case from the input file.Example(s)
sample input | sample output |
1 2 4 1 8 2 0 5 | 46 |
Note. The maximal value is attained by taking A = (1, 3), B = (2, 5), C = (4, 6).
题意:给出一组数,将这些数分成三组,记为A,B,C,求出满足sigma[(Ai-Bi)*Ci]的最大值。
sl: 首先考虑下B ,很显然B中的元素应该是最小的N个,在考虑A,C很容易看出A,C应该是满足
A>=C的关系。
所以我们只需要枚举A,C就好了。
其中包含2个优化
优化1:在计算的过程中应满足全局平均值最小。
优化2:不等式 (ai-bi)*ci+(aj-bj)*cj - {(ai-bi)*aj+(ci-bj)*cj } >0成立 即满足:
(ci-aj)*(ai-bi-cj)>0 成立。
所以ci>aj 时 ai-bi>cj
ci<aj时 ai-bi<cj
详见代码。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 typedef long long LL;
6 const int maxn = 76;
7 int T, N;
8 int ans, a[maxn], va[maxn], vc[maxn];
9 bool vis[maxn];
10 bool test(int cur) {
11 for (int i=1; i<cur; ++i) {
12 if (abs(va[cur])>abs(vc[i]) && abs(vc[cur])<abs(va[i])-abs(a[3*N-i+1])) {
13 return false;
14 }
15 if (abs(va[cur])<abs(vc[i]) && abs(vc[cur])>abs(va[i])-abs(a[3*N-i+1])) {
16 return false;
17 }
18 }
19 return true;
20 }
21 void dfs(int cur, int last, int val) {
22 if (cur==N+1) {
23 ans = max(ans, val);
24 return;
25 }
26 for (int i=cur; i<=2*N; ++i) {
27 if (!vis[i]) {
28 vis[i] = 1;
29 va[cur] = a[i];
30 for (int j=max(last+1, i+1); j<=N*2; ++j) {
31 if (!vis[j]) {
32 vc[cur] = a[j];
33 vis[j] = 1;
34 int netVal = val+(a[i]-a[3*N-cur+1])*a[j];
35 if (netVal*N>ans*cur) {
36 if (test(cur)) {
37 dfs(cur+1, j, netVal);
38 }
39 }
40 vis[j] = 0;
41 }
42 }
43 vis[i] = 0;
44 break;
45 }
46 }
47 }
48 int main()
49 {
50 scanf ("%d%d", &T, &N);
51 while (T--) {
52 for (int i=1; i<=3*N; ++i) {
53 scanf ("%d", &a[i]);
54 a[i] = -a[i];
55 }
56 sort(a+1, a+3*N+1);
57 ans = 0;
58 dfs(1, 0, 0);
59 printf ("%d\n", ans);
60 }
61 return 0;
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 typedef long long LL;
6 const int maxn = 76;
7 int T, N;
8 int ans, a[maxn], va[maxn], vc[maxn];
9 bool vis[maxn];
10 bool test(int cur) {
11 for (int i=1; i<cur; ++i) {
12 if (abs(va[cur])>abs(vc[i]) && abs(vc[cur])<abs(va[i])-abs(a[3*N-i+1])) {
13 return false;
14 }
15 if (abs(va[cur])<abs(vc[i]) && abs(vc[cur])>abs(va[i])-abs(a[3*N-i+1])) {
16 return false;
17 }
18 }
19 return true;
20 }
21 void dfs(int cur, int last, int val) {
22 if (cur==N+1) {
23 ans = max(ans, val);
24 return;
25 }
26 for (int i=cur; i<=2*N; ++i) {
27 if (!vis[i]) {
28 vis[i] = 1;
29 va[cur] = a[i];
30 for (int j=max(last+1, i+1); j<=N*2; ++j) {
31 if (!vis[j]) {
32 vc[cur] = a[j];
33 vis[j] = 1;
34 int netVal = val+(a[i]-a[3*N-cur+1])*a[j];
35 if (netVal*N>ans*cur) {
36 if (test(cur)) {
37 dfs(cur+1, j, netVal);
38 }
39 }
40 vis[j] = 0;
41 }
42 }
43 vis[i] = 0;
44 break;
45 }
46 }
47 }
48 int main()
49 {
50 scanf ("%d%d", &T, &N);
51 while (T--) {
52 for (int i=1; i<=3*N; ++i) {
53 scanf ("%d", &a[i]);
54 a[i] = -a[i];
55 }
56 sort(a+1, a+3*N+1);
57 ans = 0;
58 dfs(1, 0, 0);
59 printf ("%d\n", ans);
60 }
61 return 0;
62 }