zoukankan      html  css  js  c++  java
  • 977 AlvinZH过生日(背包DP大作战S)

    977 AlvinZH过生日

    思路

    难题。逆推DP。

    要明确dp的状态只与是否有选择权有关,而与选择权在谁手里无关。因为不论选择权在谁手里,那个人都会尽可能的获得最大的蛋糕重量。

    dp[i]表示分配到第i个物品为止,当前拥有选择权的人能获得的最大蛋糕重量,即蛋糕[i~n]的最大值。以有选择权的的人列一个转移方程,然而因为我们只知道初始选择的是AlvinZH,因此我们要逆推:

    dp[i] = max(dp[i+1], sum - dp[i+1] + val[i]);//max(不吃, 吃)

    其中sum为[i+1~n]蛋糕总质量,最后dp[1]就是AlvinZH获得的最大价值。

    注意:

    • 注释里的吃与不吃并不是一直针对同一个人的,指的是当前有选择权的人对当前蛋糕吃与不吃。
    • 整个过程没有管AlvinZH吃还是不吃,针对的对象是有选择权的那个人。

    分析

    这道题很有意思,巧妙地避过了选择权在谁手里的问题,dp求解的是有选择权能获得的最大价值,并没有考虑谁有选择权。

    逆推也很有意思,因为只知道开始时选择权在AlvinZH手里。

    好好理解吧,神奇的DP,你对它一无所知。

    参考代码一

    //
    // Created by AlvinZH on 2017/11/5.
    // Copyright (c) AlvinZH. All rights reserved.
    //
    
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n;
    int sum;//表示i+1~n块蛋糕的总量
    int val[105], dp[105];
    
    int main()
    {
        while(~scanf("%d", &n))
        {
            sum = 0;
            memset(dp, 0, sizeof(dp));
    
            for(int i = 1; i <= n; ++i)
                scanf("%d", &val[i]);
    
            for(int i = n; i >= 1; --i)
            {
                dp[i] = max(dp[i + 1], sum - dp[i + 1] + val[i]);//max(不吃, 吃)。
                sum += val[i];
            }
            printf("%d
    ", dp[1]);
        }
    }
    
  • 相关阅读:
    常见浏览器兼容性问题与解决方案
    [WinForm] VS2010发布、打包安装程序
    前端和后台对时间数值的增减操作(JavaScript和C#两种方法)
    C#类的继承,方法的重载和覆写
    web.config设置和取值
    linux nginx安装
    java Arrays.asList()和Collections.addAll()
    mysql数据库乱码
    Mysql不区分大小写
    ueditor
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/7867597.html
Copyright © 2011-2022 走看看