ZOJ Monthly, July 2012 - 补题 - zoj 3628 - Treasure Hunt III

当时比赛时候写了8题后时间不多了,就没继续做下去,不过看了下G题差不多知道怎么做了,不过感觉写起来麻烦。

今天早上写了下,果然写的挺麻烦的,至少看起来是。

因为有个循环,所以处理起来多要注意下s点上取不取值,以至于扫回来后,碰到s-1(或s+1,根据方向而定,扫到的最后一个点)点方便更新。

大致思路:和H题一样,最多一个方向上面只走一次,就是说转弯最多转一次。

dp[i][j][k]  前i秒,当前位置状态j(0,1)取不取值,s点状态(0,1),的最大值。

正反扫一次,就可以了。

代码看起来挺长的,其实一半都是复制粘贴。。。因为正反扫么。

View Code
  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 }

你可能感兴趣的:(2012)