分糖果 题解

题目描述

老师组织一群孩子围成一个圈进行游戏,游戏结束后老师会根据每个孩子的表现进行评分并给予糖果奖励。
每个孩子只能看见与自己相邻的 2 个孩子(左边的和右边的)的情况,只会关心相邻的且比自己评分低的同学的糖果数(如果相邻 2 个孩子的评分相等,则不关心)。为保证公平,相邻的孩子中,评分高的孩子必须获得更多的糖果(如果左右相邻 2 个孩子的评分相等,则不关心,即分最少的糖果1 个)。同时,为鼓励孩子的积极性,每个孩子至少都能拿到 1 个糖果。
现在需要你帮助老师来分发糖果,问怎么分配才能使要准备的糖果数最少?计算出需要的最少糖果数。

输入

输入有二行,第一行一个正整数n表示孩子的个数。
第二行n个非负整数,相邻的数用空格隔开,分别表示孩子的表现评分。

输出

一个整数,表示最少需要准备的糖果数。

样例输入 Copy

【样例1】
3
1 2 0
【样例2】
4
2 3 3 3

样例输出 Copy

【样例1】
6
【样例2】
6

样例输出 Copy

【样例1】
6
【样例2】
6

找到最低分的那个人,让他的糖果数为1,然后再去判断他的右边的人的糖果数,如郭当前的糖果无法满足要求,就从当前的人的糖果开始,往回改

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
    int le,v,ri;
};
vector<node>cc;
int ca[100005]={0};
int n,t=0,it,M=1000,m;
int main(){
    cin>>n;
    while (t++<n){
        cin>>m;
        if(m<M){M=m,it=t-1;}
        cc.push_back({t-2,m,t});
    }
    cc[0].le=n-1,cc[n-1].ri=0;
    ca[it]=1;
    for(int i=cc[it].ri;;i=cc[i].ri){
        if(i==it) {
            if(ca[i]<ca[cc[it].le]||(cc[i].v==cc[cc[it].le].v));
            else {
                ca[cc[i].le]=2;
                for(int j=cc[cc[i].le].le;;j=cc[j].le){
                    if(cc[j].v>cc[cc[j].ri].v&&ca[j]<=ca[cc[j].ri]){
                        ca[j]=ca[cc[j].ri]+1;
                    }
                    else {
//                        cout<<" lll "<<cc[j].v<<" "<<cc[cc[j].ri].v<<"   ";
//                        cout<<ca[j]<<" "<<ca[cc[j].ri]<<endl;
                        break;
                    }
                }
            }
            break;
        }
        if(cc[i].v>cc[cc[i].le].v){
            ca[i]=ca[cc[i].le]+1;
        }
        else if(cc[i].v==cc[cc[i].le].v){
            ca[i]=1;
        }
        else if(cc[i].v<cc[cc[i].le].v){
            ca[i]=1;
            if(ca[i]==0||ca[i]==ca[cc[i].le]){
                if(ca[i]==0)ca[i]=1;
                for(int j=cc[i].le;;j=cc[j].le){
                    if(cc[j].v>cc[cc[j].ri].v&&ca[j]<=ca[cc[j].ri]){
                        ca[j]=ca[cc[j].ri]+1;
                    }
                    else {
//                        cout<<" lll "<<cc[j].v<<" "<<cc[cc[j].ri].v<<"   ";
//                        cout<<ca[j]<<" "<<ca[cc[j].ri]<<endl;
                        break;
                    }
                }
            }
        }

    }
    for(int i=0;i<n;i++){
        int l=cc[i].le,r=cc[i].ri;
    }
    int ans=0;
    for(int i=0;i<n;i++){
        ans+=ca[i];
//        cout<<ca[i]<<" ";
    }
//    cout<<endl;
    cout<<ans;
    return 0;
}
//8 0 1 2 7 6 5 4 3
//8 0 1 2 7 6 2 3 0
/*
 *
20
1 3 7 9 5 10 5 0 3 7 9 1 6 8 78 2 0 7 0 0


 */
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值