首页 > 其他分享 >CF1415E New Game Plus! 题解

CF1415E New Game Plus! 题解

时间:2024-02-07 10:13:55浏览次数:30  
标签:const int 题解 sum CF1415E ans 集合 New include

解题思路

简单贪心题,我们可以把整个序列看作 \(k+1\) 个可重集,首先可以得到一个显然的结论:较大的数一定比较小的数先放入一个集合中。同样,由于每一轮 \(ans\gets ans+\max sum_i\),其中 \(sum_i\) 表示第 \(i\) 个集合的元素和,那么,我们一定会将当前的元素放入当前和最大的哪个集合。

综上,本题步骤如下:

  • 初始将每个集合的值赋为 \(0\);
  • 将数组从大到小排序,先把大的加入集合;
  • 将 \(ans\gets ans+\max sum_i\);
  • 取出最大的哪个集合,然后将当前元素加入并重新计算最大的集合。

AC 代码

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include <set>
#include <map>
#define ll long long
#define int ll
#define N 500005
int n,k,c[N];ll sum,ans;
inline bool cmp(int a,int b){
    return a>b;
}
struct Cmp{
    inline bool operator ()(
        const int a,
        const int b
    ) const {
        return a>b;
    }
};
std::set<ll,Cmp> s;
std::map<ll,ll> m;
signed main(){
    scanf("%lld%lld",&n,&k);int l;
    for(register int i=1;i<=n;++i)
        scanf("%lld",&c[i]);
    std::sort(c+1,c+n+1,cmp);
    for(register int i=1;i<=k+1;++i)
        ++m[0];s.insert(0);
    for(register int i=1;i<=n;++i){
        auto now=*s.begin();
        --m[now];if(!m[now])
            s.erase(now);
        ans+=now;++m[now+c[i]];
        s.insert(now+c[i]);
    }printf("%lld",ans);
}

标签:const,int,题解,sum,CF1415E,ans,集合,New,include
From: https://www.cnblogs.com/UncleSamDied6/p/18010669

相关文章

  • CF1416B Make Them Equal 题解
    解题思路观察可以发现,每次操作后序列元素之和不变,那么我们可以将每一次操作看作是\(a_i\)向\(a_j\)移动了\(i\timesx\)。由此可得,若序列和\(sum\bmodn\not=0\),那么一定无解,否则一定存在一个合法的操作方案。因为每次移动时移动的数应为\(i\)的倍数,所以\(a_1\)可以向......
  • CF1446C Xor Tree 题解
    解题思路与其考虑删除哪些点,不如考虑保留哪些点。考虑到和异或有关,那么我们可以把这些数倒序插入trie树中,然后我们就可以在trie树上跑一个简单的dp:若当前节点为叶子节点,那么保留,返回\(1\);若当前节点在链上,那么直接继承儿子节点;若当前节点有两个儿子,那么更新为较大儿子......
  • CF1922E Increasing Subsequences 题解
    解题思路因为可以有空集,那么我们首先构造第一段最长的连续上升的序列,那么这段序列中共有\(2^{\mids\mid}\)个上升子序列。接下来我们考虑补全剩余的,我们不妨将剩余的部分全部设为连续不增序列,那么设当前位置在第一段中有\(k\)个小于它的,那么添加这个数后可以增加\(2^{k-1}......
  • CF1413C Perform Easily 题解
    解题思路其实是很简单的一道题,考虑计算出所有\(b_i\)在减去每一个\(a_j\)后所有可能的值,将这个值按照从小到大的顺序排序,那么我们可以考虑固定最小值,查找最大值,这个时候从最小值到最大值的区间内应该每一种\(b_i\)都出现了一次。那么,我们可以使用一个桶或者map搭配双指针......
  • 洛谷P10135 暨 USACOJan2024S T2 题解
    题意简述给点一棵有\(n\)个节点的树,在每个时间点都会在某个节点出现一瓶药水,记\(p_i\)为第\(i\)个时间点出现药水的节点,定义一次遍历为从\(1\)号节点走到任意节点,要求在遍历次数最少的情况下拾取最多数量的药水。思维路径首先我们要探讨遍历次数最少的状态是怎样的。由......
  • CF1922B Forming Triangles 题解
    解题思路显然,有以下两种选择的方法:所有边一样长;两条一样长的边,第三条边小于这两条边。然后组合数计算即可。AC代码#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<vector>#definelllonglong#defineN300005intn,a[N];inlinellC3(llx){......
  • CF1922C Closest Cities 题解
    解题思路贪心,能走距离最短的城市就一定走。分别考虑\(x>y\)和\(x<y\)的情况,两种情况分别是从后向前转移和从前往后转移,分别预处理一个前缀和和后缀和即可。AC代码#include<stdio.h>#include<stdlib.h>#include<valarray>#defineN100005#definelllonglongintn......
  • CF1338B Edge Weight Assignment 题解
    解题思路一种不需要树形dp的做法。因为是一颗无根树,所以我们不妨以重心为根。首先考虑边权最少的情况。可以发现这个时候对于任意两个叶子节点,我们可以分别考虑其到根节点的路径,这样对于求其路径的异或值是没有影响的,但是在这种情况下我们可以很方便的讨论其路径的奇偶性。令......
  • ABC335 A~E 题解
    A题目大意输入一个字符串,把这个字符串的最后一位改成4后输出这个字符串。解题思路直接模拟即可AC代码#include<iostream>#include<math.h>#include<time.h>#include<stdio.h>#include<algorithm>#definelllonglonginlinevoidwork(){std::strings;s......
  • P6025 线段树 题解
    解题思路暴力做法从\(l\)到\(r\)枚举每一个数,然后建线段树,记录最大下标,然后计算答案。代码略。时间\(O(n^2)\),期望得分:\(10\)分。优化暴力我们考虑每次枚举不遍历整棵线段树。显然,贪心的,最深的最右边的节点编号最大。那么我们可以发现,如果两颗子树大小相同,那么最大节......