当时比赛时候写了8题后时间不多了,就没继续做下去,不过看了下G题差不多知道怎么做了,不过感觉写起来麻烦。
今天早上写了下,果然写的挺麻烦的,至少看起来是。
因为有个循环,所以处理起来多要注意下s点上取不取值,以至于扫回来后,碰到s-1(或s+1,根据方向而定,扫到的最后一个点)点方便更新。
大致思路:和H题一样,最多一个方向上面只走一次,就是说转弯最多转一次。
dp[i][j][k] 前i秒,当前位置状态j(0,1)取不取值,s点状态(0,1),的最大值。
正反扫一次,就可以了。
代码看起来挺长的,其实一半都是复制粘贴。。。因为正反扫么。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<climits> 6 #include<cstdlib> 7 #include<queue> 8 using namespace std; 9 typedef long long LL; 10 #define N 50010 11 #define M 9910 12 #define inf 1000000000 13 LL val[N], dp1[N][2][2], dp2[N][2][2]; 14 int main() { 15 int n, t, s; 16 while (scanf("%d%d%d", &n, &t, &s) != EOF) { 17 int lmax = min(t, n-1); 18 for (int i = 1; i <= n; ++i) 19 scanf("%lld", &val[i]); 20 if (n == 1) { 21 printf("%lld\n",val[1]); 22 continue; 23 } 24 memset(dp1, -1, sizeof(dp1)); 25 dp1[0][0][0] = 0; 26 dp1[0][1][1] = val[s]; 27 int id = s+1; 28 for (int i = 1; i <= t; ++i, ++id) { 29 if (id == n+1) id -= n; 30 if (id == s) break; 31 for (int j = 0; j < 2; ++j) { 32 if (id+1 == s || id == n && s == 1) { 33 if (dp1[i-1][0][j] != -1) { 34 dp1[i][0][j] = dp1[i-1][0][j]; 35 if (!j) dp1[i][1][j] = dp1[i-1][0][j] + val[id]; 36 } 37 if (dp1[i-1][1][j] != -1) 38 dp1[i][0][j] = max(dp1[i][0][j], dp1[i-1][1][j]); 39 continue; 40 } 41 if (dp1[i-1][0][j] != -1) { 42 dp1[i][0][j] = dp1[i-1][0][j]; 43 dp1[i][1][j] = dp1[i-1][0][j] + val[id]; 44 } 45 if (dp1[i-1][1][j] != -1) 46 dp1[i][0][j] = max(dp1[i][0][j], dp1[i-1][1][j]); 47 } 48 } 49 LL ans = 0; 50 51 52 memset(dp2, -1, sizeof(dp2)); 53 dp2[0][0][0] = 0; 54 dp2[0][1][1] = val[s]; 55 id = s-1; 56 for (int i = 1; i <= t; ++i, --id) { 57 if (id == 0) id += n; 58 if (id == s) break; 59 for (int j = 0; j < 2; ++j) { 60 if (id-1 == s || id == 1 && s == n) { 61 if (dp2[i-1][0][j] != -1) { 62 dp2[i][0][j] = dp2[i-1][0][j]; 63 if (!j) dp2[i][1][j] = dp2[i-1][0][j] + val[id]; 64 } 65 if (dp2[i-1][1][j] != -1) 66 dp2[i][0][j] = max(dp2[i][0][j], dp2[i-1][1][j]); 67 continue; 68 } 69 if (dp2[i-1][0][j] != -1) { 70 dp2[i][0][j] = dp2[i-1][0][j]; 71 dp2[i][1][j] = dp2[i-1][0][j] + val[id]; 72 } 73 if (dp2[i-1][1][j] != -1) 74 dp2[i][0][j] = max(dp2[i][0][j], dp2[i-1][1][j]); 75 } 76 } 77 for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) 78 ans = max(ans, max(dp2[lmax][i][j], dp1[lmax][i][j])); 79 80 id = s; 81 for (int i = 0; i <= t; ++i, ++id) { 82 if (id == n+1) id -= n; 83 if (id == s && i) break; 84 int d = t-i*2; 85 d = min(n-i-1, d); 86 if (d > 0 && d+i+1 != n) { 87 for (int j = 0; j < 2; ++j) for (int k = 0; k < 2; ++k) { 88 LL t; 89 t = max(dp2[d][0][k], dp2[d][1][k]); 90 if (k && t != -1) t-= val[s]; 91 if (t != -1) ans = max(ans, dp1[i][j][k] + t); 92 } 93 } 94 } 95 96 id = s; 97 for (int i = 0; i <= t; ++i, --id) { 98 if (id == 0) id += n; 99 if (id == s && i) break; 100 int d = t-i*2; 101 d = min(n-i-1, d); 102 if (d > 0 && d+i+1 != n) { 103 for (int j = 0; j < 2; ++j) for (int k = 0; k < 2; ++k) { 104 LL t; 105 t = max(dp1[d][0][k], dp1[d][1][k]); 106 if (k && t != -1) t -= val[s]; 107 if (t != -1) ans = max(ans, dp2[i][j][k] + t); 108 } 109 } 110 } 111 printf("%lld\n", ans); 112 } 113 return 0; 114 }