【ZJOI2017 Round1练习】D8T2 sequence(DP)

题意:

思路:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <map>
 7 using namespace std;
 8 
 9 const int N = 153, INF = -0x3f3f3f3f;
10 int n, m, ans[N], v[N], a[N], last[N][N], f[N][N][N], g[N][N][N];
11 map<int, int> hash;
12 
13 inline void upt(int &x, const int &y) {
14     if (x < y) x = y;
15 }
16 
17 char ch;
18 inline int read() {
19     int res = 0, sgn = 0;
20     while (ch = getchar(), ch < '0' || ch > '9') if (ch == '-') break;
21     ch == '-' ? sgn = 1 : res = ch - 48;
22     while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48;
23     return sgn == 0 ? res : -res;
24 }
25 
26 int main() {
27   freopen("sequence.in", "r", stdin);
28   freopen("sequence.out", "w", stdout);
29 
30     n = read();
31     for (int i = 1; i <= n; ++i) v[i] = read();
32     for (int i = 1; i <= n; ++i) {
33         a[i] = read();
34         if (hash[a[i]] == 0) hash[a[i]] = ++m;
35     }
36     for (int i = 1; i <= n; ++i) {
37         for (int j = 1; j <= m; ++j) last[i][j] = last[i - 1][j];
38         last[i][hash[a[i]]] = i;
39     }
40     memset(f, INF, sizeof(f));
41     memset(g, INF, sizeof(g));
42     for (int i = 1; i <= n; ++i) {
43         for (int j = 0; j <= n; ++j)
44             if (i + j <= n)
45                 f[i][i][j] = g[i][i][j] = v[j + 1];
46             else     break;
47         f[i][i - 1][0] = g[i][i - 1][0] = 0;
48     }
49     for (int l = 1; l <= n; ++l)
50         for (int i = 1; i <= n; ++i) {
51             int j = i + l;
52             if (j > n) break;
53             for (int k = 0; k <= n; ++k) {
54                 if (j + k > n) break;
55                 upt(f[i][j][k], f[i][j - 1][0] + v[k + 1]);
56                 upt(g[i][j][k], f[i][j - 1][0] + v[k + 1]);
57                 int p = hash[a[j] + 1], q = hash[a[j] - 1];
58                 for (int h = last[j][p]; h >= i; h = last[h - 1][p])
59                     upt(f[i][j][k], f[i][h][k + 1] + f[h + 1][j - 1][0]);
60                 for (int h = last[j][q]; h >= i; h = last[h - 1][q]) {
61                     upt(f[i][j][k], g[i][h][k + 1] + f[h + 1][j - 1][0]);
62                     upt(g[i][j][k], g[i][h][k + 1] + f[h + 1][j - 1][0]);
63                 }
64             }
65         }
66     ans[0] = 0;
67     for (int i = 1; i <= n; ++i) {
68         upt(ans[i], ans[i - 1]);
69         for (int j = 0; j < i; ++j)
70             upt(ans[i], ans[j] + f[j + 1][i][0]);
71     }
72     printf("%d\n", ans[n]);
73     return 0;
74 }

 

posted on 2017-03-13 20:16  myx12345  阅读(107)  评论(0编辑  收藏  举报

导航