只因国福利

只因鸡国福利

鸡国为了表彰鸡国每一只鸡在过去一年的优秀表现,打算在接下来的 n 天中每天给鸡国的一只鸡发 1 袋或者 2 袋“鸡币”(鸡国的通用货币)作为福利。国王要求每天来领钱鸡
互不相同,即来领过钱的鸡不能再来,否则将受到严厉的处罚。 
但聪明的鸡国老百姓侦察后发现国王每天发的钱袋子里面装的钱数量是不一样的(同一天的相同),第 i 天发的每一袋钱为 a i 元。如果第 i 天来领钱的鸡领 1 袋钱,它可以获得ai 元的“鸡币”,如果它领 2 袋钱,则可以获得 2×ai 元“鸡币”,当然它也可以放弃,则第i 天的钱国王收回国库。 
由于鸡国生活条件优越和鸡的贪念等原因,当第 i 天领钱的鸡同时满足以下两个条件时它才会感到幸福: 
(1)领到的钱不能低于鸡国的平均收入 m 元。 
(2)要跟它前面领了钱且感到幸福的鸡一样幸福或者更幸福。 
仁慈的国王希望鸡国的每一只鸡都能感到幸福,请你帮国王规划一下在这 n 天中怎样给每一只发钱才能让最多的鸡感到幸福? 

输入

输入共 2 行。 
第 1 行输入两个整数 n 和 m,分别表示发钱的天数(或理解为来领钱的鸡数)和鸡国的平均收入。 
第 2 行 n 个正整数 ai  (1≤i≤n),依次表示第 i 天发的一袋钱中的“鸡币”为 ai 元。。 

输出

输出 1 行一个整数,表示最多可以让多少只鸡感到幸福。 

样例输入 Copy

2 1
2 1

样例输出 Copy

2

训练时想到最长不下降子序列,但是没想到如何处理*2这个问题

后来看网上题解得到方法,,不过某个blog被随手捏的数据我hack了..就让我不太信他的代码了,于是改进了自己原先的代码

最长不下降子序列的O(nlogn)做法可以看之前的博客

 

代码
 #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
int n, m, ans;
int a[100001], b[100001];//b[i]存长度为i时最后一个元素
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    b[0] = -1e9;
    for (int i = 1; i <= n; i++)
    {
        int l = 0, r = ans, p = 0, tem;
        if (a[i] >= m)
        {
            while (l < r)//二分查找mid最大的(小于等于a[i]的b[mid])
            {
                int mid = (l + r + 1) >> 1;
                if (b[mid] <= a[i])l = mid;
                else r = mid - 1;
            }
            p = r + 1;//先存一下
        }
        if (a[i] * 2 >= m)
        {
            l = 0, r = ans;
            while (l < r)
            {
                int mid = (l + r + 1) >> 1;
                if (b[mid] <= a[i] * 2)l = mid;
                else r = mid - 1;
            }
            ans = max(ans, r + 1);
            b[r + 1] = a[i] * 2;
        }
        if (a[i] >= m)//保证"第i个鸡领一袋产生结果和第i个鸡领两袋结果一样"时答案的最优
            b[p] = a[i], ans = max(p, ans);
    }
    cout << ans;
    return 0;
}

 

posted @ 2022-12-20 23:43  qbning  阅读(79)  评论(0编辑  收藏  举报
描述