D. Lizard Era: Beginning

 

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     }

 

原文地址:https://www.cnblogs.com/towerbird/p/11240217.html