牛客网--19校招--获得最多的奖金

本文介绍了一个有趣的算法问题,即如何通过两次切割将一系列带有不同奖金数额的红包分成三组,使得第一组和第三组的奖金总额相等,从而最大化小明能够获得的奖金。文章详细解释了算法的实现过程,包括使用双指针策略从前向后和从后向前遍历红包列表,调整两组红包的总和,直至找到最佳的切割点。
摘要由CSDN通过智能技术生成

题目描述

小明在越南旅游,参加了当地的娱乐活动。小明运气很好,拿到了大奖, 到了最后的拿奖金环节。小明发现桌子上放着一列红包,每个红包上写着奖金数额。

现在主持人给要求小明在这一列红包之间“切”2刀,将这一列红包“切”成3组,并且第一组的奖金之和等于最后一组奖金和(允许任意一组的红包集合是空)。最终第一组红包的奖金之和就是小明能拿到的总奖金。小明想知道最多能拿到的奖金是多少,你能帮他算算吗。

 

举例解释:桌子上放了红包  1, 2, 3, 4, 7, 10。小明在“4,7”之间、“7,10” 之间各切一刀,将红包分成3组 [1, 2, 3, 4]   [7]   [10],其中第一组奖金之和=第三组奖金之和=10,所以小明可以拿到10越南盾。

输入描述:

第一行包含一个正整数n,(1<=n<= 200 000),表示有多少个红包。

第二行包含n个正整数d[i],表示每个红包包含的奖金数额。其中1<= d[i] <= 1000 000 000

输出描述:

小明可以拿到的总奖金

示例1

输入

复制

5
1 3 1 1 4

输出

复制

5

说明

[1,3,1]  [ ]   [1,4] ,其中第一组奖金和是5,等于第三组奖金和。所以小明可以拿到5越南盾

示例2

输入

复制

5
1 3 2 1 4

输出

复制

4

说明

[1,3]   [2,1]  [4],小明可以拿到4越南盾

示例3

输入

复制

3
4 1 2

输出

复制

0

说明

[ ]  [4, 1, 2] [ ] ,小明没办法,为了保证第一组第三组相等,只能都分成空的。所以小明只能拿到0越南盾。

设置两个标志,Low,High,分别从前向后,从后向前遍历,如果前面的红包值和大时,后面的向前移动一位,加上之后继续比较。如果后面的红包值和大时,前面的向后移动一位,加上之后继续比较。

如果前后当前值相等,记录下这个值,前后同时向中间动一位,观察是否还存在相等的情况下更大的红包值

本题有一组数据很大,int无法存储,需用long类型或long long类型

#include<stdio.h>
int main()
{
    long long n,Low=0,High,sum1=0,sum2=0,t=0;
    scanf("%lld",&n);
    High=n-1;
    long long a[n],i;
    for(i=0;i<n;i++)
    {
        scanf("%lld",&a[i]);
    }
    sum1=a[Low];
    sum2=a[High];
    while(High>=Low)
    {
        if(sum1>sum2)
        {
            High--;
            sum2+=a[High];
        }
        else if(sum1<sum2)
        {
            Low++;
            sum1+=a[Low];
        }
        else if(sum1==sum2)
        {
            t=sum1;
            Low++;
            High--;
            sum1+=a[Low];
            sum2+=a[High];
        }
    }
    printf("%lld\n",t);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值