【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 }
null