• 洛谷算法题解:Bear and Bowling


    题目描述

    题面翻译

    • 给定一个长度为 n n n 的序列 a 1 … n a_{1\dots n} a1n
    • 你要求一个 a a a 的子序列 b 1 … m b_{1\dots m} b1m(可以为空),使得 ∑ i = 1 m i b i \sum_{i=1}^m ib_i i=1mibi 的值最大。
    • n ≤ 1 0 5 n \le 10^5 n105 ∣ a i ∣ ≤ 1 0 7 |a_i| \le 10^7 ai107
    • 时间限制:6秒。

    题目描述

    Limak is an old brown bear. He often goes bowling with his friends. Today he feels really good and tries to beat his own record!

    For rolling a ball one gets a score — an integer (maybe negative) number of points. Score for i i i -th roll is multiplied by i i i and scores are summed up. So, for k k k rolls with scores s 1 , s 2 , . . . , s k s_{1},s_{2},...,s_{k} s1,s2,...,sk , total score is . Total score is 0 0 0 if there were no rolls.

    Limak made n n n rolls and got score a i a_{i} ai for i i i -th of them. He wants to maximize his total score and he came up with an interesting idea. He will cancel some rolls, saying that something distracted him or there was a strong wind.

    Limak is able to cancel any number of rolls, maybe even all or none of them. Total score is calculated as if there were only non-canceled rolls. Look at the sample tests for clarification. What maximum total score can Limak get?

    输入格式

    The first line contains single integer n n n ( 1 < = n < = 1 0 5 1<=n<=10^{5} 1<=n<=105 ).

    The second line contains n n n space-separated integers a 1 , a 2 , . . . , a n a_{1},a_{2},...,a_{n} a1,a2,...,an ( ∣ a i ∣ < = 1 0 7 ) |a_{i}|<=10^{7}) ai<=107) - scores for Limak’s rolls.

    输出格式

    Print the maximum possible total score after choosing rolls to cancel.

    样例 #1

    样例输入 #1

    5
    -2 -8 0 5 -3
    
    • 1
    • 2

    样例输出 #1

    13
    
    • 1

    样例 #2

    样例输入 #2

    6
    -10 20 -30 40 -50 60
    
    • 1
    • 2

    样例输出 #2

    400
    
    • 1

    提示

    In first sample Limak should cancel rolls with scores − 8 -8 8 and − 3 -3 3 . Then he is left with three rolls with scores − 2 , 0 , 5 -2,0,5 2,0,5 . Total score is 1 ⋅ ( − 2 ) + 2 ⋅ 0 + 3 ⋅ 5 = 13 1·(-2)+2·0+3·5=13 1(2)+20+35=13 .

    In second sample Limak should cancel roll with score − 50 -50 50 . Total score is 1 ⋅ ( − 10 ) + 2 ⋅ 20 + 3 ⋅ ( − 30 ) + 4 ⋅ 40 + 5 ⋅ 60 = 400 1·(-10)+2·20+3·(-30)+4·40+5·60=400 1(10)+220+3(30)+440+560=400 .

    算法思想(动态规划)

    状态表示

    f [ i ] [ j ] f[i][j] f[i][j]表示在数列的前 i i i个数中已经选择 j j j个数时的最大值。

    状态计算

    f [ i ] [ j ] = m a x { f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − 1 ] + j ∗ x i , f [ i − 1 ] [ j − 2 ] + ( j − 1 ) ∗ x i , . . . , f [ i − 1 ] [ 1 ] + 2 ∗ x i , f [ i − 1 ] [ 0 ] + x i } f[i][j]=max\{f[i-1][j], f[i-1][j-1]+j*x_i,f[i-1][j-2]+(j-1)*x_i,...,f[i-1][1]+2*x_i,f[i-1][0]+x_i\} f[i][j]=max{f[i1][j],f[i1][j1]+jxi,f[i1][j2]+(j1)xi,...,f[i1][1]+2xi,f[i1][0]+xi},其中 j < = i j<=i j<=i

    由于第 i i i阶段的状态只与 i − 1 i-1 i1阶段的状态有关,因此可以进行状态优化,使用一维状态进行计算,即 f [ j ] = m a x { f [ j ] , f [ j − 1 ] + j ∗ x i , f [ j − 2 ] + ( j − 1 ) ∗ x i , . . . , f [ 1 ] + 2 ∗ x i , f [ 0 ] + x i } f[j] = max\{f[j], f[j-1]+j*x_i,f[j-2]+(j-1)*x_i,...,f[1]+2*x_i,f[0]+x_i\} f[j]=max{f[j],f[j1]+jxi,f[j2]+(j1)xi,...,f[1]+2xi,f[0]+xi}

    需要注意的是,在计算第 i i i阶段的状态时,只能使用 i − 1 i-1 i1阶段的状态,为了防止状态污染,需要从大到小枚举 j j j

    如果从小到大枚举 j j j,那么在计算 f [ j ] f[j] f[j]之前, f [ j − 1 ] f[j-1] f[j1]将会被更新为第 i i i阶段的状态,与优化之前不符,称为状态污染

    初始状态

    由于数列中存在负数,因此求最大值时,f[j]应输出化为 − ∞ -∞ ;除此之外, f [ 0 ] = 0 f[0]=0 f[0]=0

    代码实现

    #include 
    #include 
    using namespace std;
    typedef long long LL;
    const int N = 100010;
    LL f[N];
    int main()
    {
        LL n, x;
        scanf("%lld", &n);
        memset(f, 0xbf, sizeof f); //将f初始化为无穷小
        f[0] = 0;
        for (int i = 1; i <= n; i ++ )
        {
            scanf("%lld", &x);
            for(int j = i; j > 0; j --)
                f[j] = max(f[j], f[j - 1] + j * x);
        }
        LL ans = -1e18;
        for(int i = 1; i <= n; i ++) ans = max(ans, f[i]);
        printf("%lld", ans);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    Suc-Ala-Ala-Pro-Asp-pNA,CAS号: 165174-58-3
    《痞子衡嵌入式半月刊》 第 83 期
    Dreambooth工作原理
    基于 Redisson 和 Kafka 的延迟队列设计方案
    先进制造aps专题四 计划型简单aps系统(plan)和排产型复杂aps系统(Scheduling)的区别
    Winform的UI帮助类——部分组件会使用到DevExpress组件
    【深入浅出Java并发编程指南】「源码分析篇」透析ThreadLocal线程私有区域的运作机制和源码体系
    Git用户名/密码/邮箱,及设置git配置
    云计算场景下,如何快速定位出虚拟机reboot/shutdown引发的故障
    pycharm中出现这个的原因是什么,如何解决?
  • 原文地址:https://blog.csdn.net/qiaoxinwei/article/details/126274400