码迷,mamicode.com
首页 > 其他好文 > 详细

<gym101673G. A Question of Ingestion> (DP)

时间:2018-05-05 01:03:01      阅读:391      评论:0      收藏:0      [点我收藏+]

标签:name   \n   names   include   memset   splay   今天   alt   pre   

题意:有最多100天 每天有一个食物量 你一开始有一个最大胃口表示你最开始能吃多少食物

   如果你昨天吃了 那么今天的胃口为昨天的2/3 如果你前天吃了 昨天没吃 那么你的胃口可以恢复到前天的情况

   如果你有连续两天没吃了 那么你就可以恢复到最大胃口了 问怎样安排使一共吃到的食物最多

 

题解:就裸裸的DP了,反正从没出过DP(的DP选手

   dp[i][j][k]表示第i天结束后 当前的胃口能级为j 这一天进行的操作k k为0表示今天吃了 k为1表示今天没吃

   那么转移也没什么难的了  转移模拟这几种状态即可

   今天吃由昨天转移来的 

   dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - 1][0] + 今天吃);
       dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j][0]);  今天不吃

   今天吃由前天转移来的  dp[i][j][0] = max(dp[i][j][0], dp[i - 2][j][0] + 今天吃]));

   还要处理一下由大前天转移过来的 这时候你今天吃 能级就为1 今天不吃能级就为0

   反正就xjb搞吧... 我和铜牌题打起来了

 

技术分享图片
#include <bits/stdc++.h>
using namespace std;

int q[105];
int e[105];
int dp[105][105][5];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    memset(dp, 0, sizeof(dp));

    for(int i = 1; i <= n; i++) scanf("%d", &q[i]);
    e[1] = m;
    for(int i = 2; i <= n; i++) e[i] = e[i - 1] * 2 / 3;

    for(int i = 1; i <= n; i++)
    {
        dp[i][1][0] = min(q[i], e[1]);
        if(i > 2)
        {
            for(int j = 0; j <= i - 3; j++)
            {
                dp[i][1][0] = max(dp[i][1][0], dp[i - 3][j][0] + min(q[i], e[1]));
                dp[i][1][0] = max(dp[i][1][0], dp[i - 3][j][1] + min(q[i], e[1]));
            }
        }

        if(i > 1)
        {
            for(int j = 0; j <= i - 2; j++)
            {
                dp[i][0][1] = max(dp[i][0][1], dp[i - 2][j][0]);
                dp[i][0][1] = max(dp[i][0][1], dp[i - 2][j][1]);
            }
        }

        for(int j = 1; j <= i; j++)
        {
            dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - 1][0] + min(q[i], e[j]));
            dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j][0]);
            if(i > 1)
                dp[i][j][0] = max(dp[i][j][0], dp[i - 2][j][0] + min(q[i], e[j]));
        }
    }

    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j <= i; j++)
        for(int k = 0; k < 2; k++)
            ans = max(ans, dp[i][j][k]); 
    }
    printf("%d\n", ans);
    return 0;
}
/*
8 900
900 600 40 400 20 266 10 177
*/
View Code

 

<gym101673G. A Question of Ingestion> (DP)

标签:name   \n   names   include   memset   splay   今天   alt   pre   

原文地址:https://www.cnblogs.com/lwqq3/p/8993251.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!