【DP + 思维】A Question of Ingestion Gym - 101673G

 A Question of Ingestion Gym - 101673G

给出n天,有一个饭量m。若连续吃饭 j 天则,每次能吃的量是m乘以(2/3)^ j 。或者你可以选择中途休息。

若休息1天,则减少一个 j 次的2/3 。。若连续休息两天,则下一次又可以吃 m 的量。

第二行给出的是当天能得到的最多的摄入量。你在当天得到的能量不能超出这个上限。

询问最后能得到最大的能量总和。

我又双叒叕!读错题了!!!


  dp[ i ][ j ]来记录在第 i 天,连续摄入第 j 天时能得到的总量的最大值。dp[ i ][ j ]的值要么是前一天选择吃饭转移来的,或者是前一天没有吃饭转移过来的。需要注意的是dp[ i ][ 1 ]可能是大前天转移过来的,这表示中间的两天选择不吃饭。

#include <bits/stdc++.h>
using namespace std;

int dp[105][105];
int a[105], b[105];
////dp[i][j][k] : 表示今天是第i天,能量级别为j级, 今天吃了是1,没吃是0;
////今天吃昨天转来的:   dp[i][j][1] = max(dp[i][j][1], dp[i-1][j-1][1] + 今天吃)
////                     dp[i][j][0] = max(dp[i][j][0], dp[i-1][j][1] + 今天不吃)
////今天吃前天转来的:   dp[i][j][1] = max(dp[i][j][1], dp[i-2][j-1][1] + 今天吃)
////                     dp[i][j][0] = max(dp[i][j][0], dp[i-2][j][1] + 今天不吃)
////今天吃大前天转来的: dp[i][j][1] = max(dp[i][j][1], dp[i-3][j][1] + 今天吃,能量为m)

/*
dp[i][j] 正准备吃第i个时,已经连续吃了j个所得到的能量

*/
    
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    b[1] = m;
    for(int i = 2; i <= n; i++)
        b[i] = (floor)(b[i-1] * 2 / 3);
    for(int i = 1; i <= n; i++)
    {
        dp[i][1] = min(a[i], b[1]);
    }
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n + 1; j++)
        {
            if(i >= 1)
            {
                dp[i][j] = max(dp[i][j], dp[i-1][j-1] + min(a[i], b[j]));
            }

            if(i >= 2)
            {
                dp[i][j] = max(dp[i][j], dp[i-2][j] + min(a[i], b[j]));
            }

            if(i >= 3)
            {
                dp[i][1] = max(dp[i][1], dp[i-3][j] + min(a[i], b[1]));
            }

            ans = max(ans, dp[i][j]);
            ans = max(ans, dp[i][1]);
        }
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_41037114/article/details/83627435