标签:key contest ble possible 处理 The 答案 final 最大
http://codeforces.com/contest/585/problem/D
1、meet in the middle 里上半部分搜索为d1()、下半部分搜索为d2(),
d1()的内容很简单:搜索,直到超过边界,记录状态值,
d2()的内容也很简单:搜索,直到超过边界,合并d1()状态值,按照题目做出处理
2、设d1()搜索出的三个值为a、b、c,d2()为a‘、b‘、c’,要求a+a‘==b+b‘、a+a‘==c+c‘,
但因为a、a‘不在一个函数里,我们变形为a-b=b‘-a‘、a-c=c‘-a‘。
为了方便,我们把a-b、a-c放入一个数字s里,a‘-b‘、a‘-c‘放入一个数字s‘里,有s==s‘即可得到三个attitude相等。
因为a-c最大为2e7,我们把a-b扩大2e7倍再与a-c相加就得到s
3、题目还要求最后的attitude不仅要相等,还要尽量最大,
对于每个s,我们记录其a值,将<s,a>存入HashMap,就可在d2()里得到a+a‘
题目还要求打印步骤,对于每个状态s,我们用一个3进制数表示步骤,将<s,k>存入HashMap
1 static final int max = (int) (3e7 + 100);
2 static int[] a = new int[1000];
3 static int[] b = new int[1000];
4 static int[] c = new int[1000];
5 static int n;
6
7 static HashMap<Long, Integer> maa = new HashMap<>();
8 static HashMap<Long, Integer> mk = new HashMap<>();
9
10 //最终答案的a值
11 static long ansaa = Long.MIN_VALUE;
12 //表示d1各步骤的3进制数、表示d2各步骤的3进制数
13 static long ansk1, ansk2;
14
15 public static void main(String[] args) {
16
17 IO io = new IO();
18 n = io.nextInt();
19 for (int i = 0; i < n; i++) {
20 a[i] = io.nextInt();
21 b[i] = io.nextInt();
22 c[i] = io.nextInt();
23 }
24
25 d1(0, 0, 0, 0, 0);
26 d2(n / 2 + 1, 0, 0, 0, 0);
27 if (ansaa == Long.MIN_VALUE) io.println("Impossible");
28 else {
29 String[] s = new String[]{"LM", "LW", "MW"};
30 int[] ans = new int[n];
31 //第一步被无限*3,最后一步没有*3,不难发现是倒叙
32 for (int i = n / 2; i >= 0; i--, ansk1 /= 3) ans[i] = (int) ansk1 % 3;
33 for (int i = n - 1; i > n / 2; i--, ansk2 /= 3) ans[i] = (int) ansk2 % 3;
34 for (int i = 0; i < n; i++) io.println(s[ans[i]]);
35 }
36 }
37
38 //[0,n/2],k是记录步骤的3进制
39 static void d1(int task, int aa, int bb, int cc, int k) {
40 if (task > n / 2) {
41 long s = (aa - bb) * max + aa - cc;
42 if (maa.containsKey(s) == false || maa.get(s) < aa) {
43 maa.put(s, aa);
44 mk.put(s, k);
45 }
46 return;
47 }
48 d1(task + 1, aa + a[task], bb + b[task], cc, k * 3);
49 d1(task + 1, aa + a[task], bb, cc + c[task], k * 3 + 1);
50 d1(task + 1, aa, bb + b[task], cc + c[task], k * 3 + 2);
51 }
52
53
54 //[n/2+1,n-1]
55 static void d2(int task, long aa, int bb, int cc, long k) {
56 if (task > n - 1) {
57 long s = (bb - aa) * max + cc - aa;
58 if (maa.containsKey(s)) if (maa.get(s) + aa > ansaa) {
59 ansaa = maa.get(s) + aa;
60 ansk1 = mk.get(s);
61 ansk2 = k;
62 }
63 return;
64 }
65 d2(task + 1, aa + a[task], bb + b[task], cc, k * 3);
66 d2(task + 1, aa + a[task], bb, cc + c[task], k * 3 + 1);
67 d2(task + 1, aa, bb + b[task], cc + c[task], k * 3 + 2);
68 }
标签:key contest ble possible 处理 The 答案 final 最大
原文地址:https://www.cnblogs.com/towerbird/p/11240217.html