蓝桥杯备赛-前缀和-可获得的最小取值

问题描述

妮妮学姐手头有一个长度为 nn 的数组 aa,她想进行 kk 次操作来取出数组中的元素。每次操作必须选择以下两种操作之一:

  • 取出数组中的最大元素。
  • 取出数组中的最小元素和次小元素。

妮妮学姐希望在进行完 kk 次操作后,取出的数的和最小。她感觉有些困难,于是请擅长贪心的你帮助她解决这个问题。

输入格式

第一行输入两个整数 nn 和 kk ,表示数组长度和操作次数。

第二行输入 nn 个整数表示数组 aa 。

数据范围保证 3≤n≤2×105,1≤ai≤109,1≤k≤99999,2k<n3≤n≤2×105,1≤ai​≤109,1≤k≤99999,2k<n 。

输出格式

样例输入

复制代码
5 1
2 5 1 10 6

样例输出

cpp 复制代码
3#include <iostream>
#include<vector>
#include <algorithm>
#include <climits> // 用于 INT_MAX 或 LLONG_MAX
using namespace std;
//贪心不对:每次在操作(1)和操作(2)中选较小的值。
//例如{3, 1, 1, 1, 1, 1, 1},做k=3次操作,每次都按贪心法
//做3次操作(2),结果是6。但是正确答案是做3次操作(1),结果是5。
//设操作(2)做p次,操作(1)做k-p次:ans=sum[2p]+sum[n]-sum[n+p-k],尝试所有可能的p
int main()
{
  int n,k;
  cin>>n>>k;//不是n,k
  vector<int> a(n+1,0);
  vector<long long> sum(n+1,0);
  for(int i=1;i<=n;i++)
  {
    cin>>a[i];
  }
  sort(a.begin()+1,a.end());
  //对1-n进行排序
  //!!!!!!a和sum要分开写,sum的计算要在排序之后
  for(int i=1;i<=n;i++)
  {
    sum[i]=sum[i-1]+a[i];
  }
  long long ans=LLONG_MAX;//存疑
  for(int p=1;p<=k;p++)
  {
    ans=min(ans,sum[2*p]+sum[n]-sum[n-k+p]);//不是2p
  }
  cout<<ans;
  return 0;
}

说明

对于样例,我们通过操作 22 取出 11 和 22 可以获得最小值。

相关推荐
bIo7lyA8v9 分钟前
算法中的随机化思想及其复杂度收益评估的技术8
算法
数据法师14 分钟前
视频文件重复检测工具:基于哈希与视频指纹的三级筛选机制
算法·音视频·哈希算法
其实防守也摸鱼16 分钟前
软件安全与漏洞--Windows底层原理与软件逆向工程基础
linux·网络·数据库·算法·安全·安全架构·软件安全与漏洞
bIo7lyA8v1 小时前
算法稳定性与数据分布的内在联系研究的技术8
算法
SHARK_pssm1 小时前
【数据结构——树与堆】
c语言·数据结构·经验分享·笔记
blueman88881 小时前
VS2022 切换定义(F12 / Go to Definition)反应慢
c++·visual studio
bIo7lyA8v2 小时前
算法可视化对教学与调试效率的影响分析的技术8
算法
凡人叶枫2 小时前
Effective C++ 条款35:考虑 virtual 函数以外的其他选择
java·c++·spring
郝学胜-神的一滴2 小时前
CMake 017:彩色日志输出实战
linux·c语言·开发语言·c++·软件工程·软件构建·cmake
hunterkkk(c++)2 小时前
优先队列启发式最短路径快速算法(优化SPFA)-HEAP_SPFA算法
算法