HDU - 2182 - Frog(基础dp)

题目链接
题目大意:一只青蛙可以从\(0\)开始在\([0, n)\)的区间内向右跳跃,每次跳跃之后可以获得落点的值(起点也算),每步的大小为\([a, b]\),最多跳\(k\)步,问你最大值。
  我们不妨先想象所有的情况, 第一步,青蛙可以从起点跳到\(e(e\in [a,b])\)。第二步,青蛙可以从之前落下的地方\(s\)起跳(\(s\in [a, b]\)),跳到\(e(e\in [a+s,b+s])\),显然,青蛙每步可以获得的值就是起点的值加上落点的值,而最大值就是起点值加上落点值的最大值。设\(s\)为起点的位置,\(e\)为终点的位置,\(k\)为第\(k\)步,\(a[e]\)\(e\)点的值,那么状态转移方程就是\(dp[e][k] = max(dp[e][k], dp[s][k-1]+a[k])\)

const int maxn = 1e2+10;
int dp[maxn][maxn], arr[maxn];
int main(void) {
    int t;
    scanf("%d", &t);
    while(t--) {
        int n, a, b, m;
        scanf("%d%d%d%d", &n, &a, &b, &m);
        zero(dp);
        for (int i = 0; i<n; ++i) scanf("%d", &arr[i]);
        int ans = 0; dp[0][0] = arr[0];
        for (int i = 1; i<=m; ++i) //步数
            for (int j = 0; j<n; ++j) //起点位置
                if (dp[j][i-1])
                    for (int k = a+j; k<=b+j && k<n; ++k) { //每步的大小
                        dp[k][i] = max(dp[k][i], dp[j][i-1]+arr[k]);
                        ans = max(ans, dp[k][i]);
                    }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/shuitiangong/p/12650634.html