• 【Candy】cpp


    题目

    There are N children standing in a line. Each child is assigned a rating value. 

    You are giving candies to these children subjected to the following requirements:

    • Each child must have at least one candy.
    • Children with a higher rating get more candies than their neighbors.

    What is the minimum candies you must give?

    代码

    class Solution {
    public:
        int candy(vector<int>& ratings) {
                const size_t len = ratings.size();
                std::vector<int> candyNum(len);
                // from left to right
                for (size_t i = 1; i < len; ++i){
                    if (ratings[i] > ratings[i-1]) candyNum[i] = candyNum[i-1] + 1;
                }
                // from right to left
                for (size_t i = 1; i < len; ++i){
                    if (ratings[len-i-1]>ratings[len-i]){
                        candyNum[len-i-1] = std::max(candyNum[len-i]+1,candyNum[len-i-1]);
                    }
                }
                return std::accumulate(candyNum.begin(), candyNum.end(), len);
        }
    };

    Tips:

    大体思路是greedy。题目的需求可以分解为如下两个条件:

    a. ratings从左向右的子递增序列,candy也要是递增的

    b. ratings从右向左的子递增序列,candy同样也是递增的

    具体:

    1. 从左往右遍历一次,保证从左→右的递增序列,candy都是递增1的(相当于先对条件a进行了一次greedy,保证了条件a是充分的)

    2. 从右往左遍历一次,保证从右→左的递增序列,candy也是至少递增1的(相当于再对条件b进行了一次greedy,保证了条件b是充分的,但是不能破坏条件a成立)

    代码中一条关键语句如下:

    std::max(candyNum[len-i]+1,candyNum[len-i-1]);

    举个例子,ratings = {4,2,3,4,1}

    从左往右走完第一遍 则candyNum = {0,0,1,2,0}

    现在开始从右往左走,如果没有max这条语句,则走完右数第二个元素就变成了 candyNum = {0,0,1,1,0}

    这样为了满足条件b就破坏了条件a,所以max这条语句是必要的。

    从总体思路上来说:两个greedy并不能直接得到全局的最优解,需要调节两个greedy之间的矛盾,而max这条语句就是调节矛盾的

    ================================================

    第二次过这道题,大体思路记得比较清楚,就是红字的部分,两个greedy之间不能破坏彼此的条件。

    class Solution {
    public:
        int candy(vector<int>& ratings) {
                vector<int> candys(ratings.size(),1);
                // from left to right
                for ( int i=1; i<ratings.size(); ++i )
                {
                    if ( ratings[i]>ratings[i-1] ) candys[i] = candys[i-1]+1;
                }
                // from right to left
                for ( int i=ratings.size()-1; i>0; --i )
                {
                    if ( ratings[i-1]>ratings[i] )
                    {
                        candys[i-1] = std::max( candys[i-1], candys[i]+1 );
                    }
                }
                return accumulate(candys.begin(), candys.end(), 0);
        }
    };
  • 相关阅读:
    WebRTC之完整搭建Jitsi Meet指南
    使用Jibri进行Jitsi Meet视频录制
    完整开源免费视频会议Jitsi-meet安装教程
    iOS聊天起泡(背景图片被拉伸不变形)----转载--待验证
    技术人对赚钱的思考与摸索
    模板引擎的思考
    SpringBoot单文件与多文件上传
    数据库被删之反思
    分布式配置中心之思考
    正版office产品密钥-激活码
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4459460.html
Copyright © 2020-2023  润新知