IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> D.背单词的小智(二分) -> 正文阅读

[C++知识库]D.背单词的小智(二分)

题目描述

小智在刚刚结束的 CET-4 考试中顺利通过了!现在,他要开始备战 CET-6 了。

可是,他的单词功底太差了,于是他准备开始摆烂背单词。

可是,人脑的能力是有限的,小智的大脑每一天都会有一个记忆的上限,如果超过这个上限,再多的单词也记不下了。

有一天,小智在背单词的时候想到了一个问题,你能帮帮他吗?

小智一共有?n?个单词需要背,第?ii?个单词所拥有的「精神值」为?a_i

小智每天的记忆力都是有上限?mm?的。如果小智在第?ii?天内背完了?[l,r]内的单词,那么这些单词将会占用小智?C_i = \sum\limits_{j=l} ^ r a_j^2?的记忆力。

小智需要在最多?kk?天里把这些单词全部背完,他希望你在把这些单词背完的同时,让他每天需要的记忆力的最大值尽可能小。

形式化地,你需要将一个序列最多分为?k段,请你找到一个最小的?m,使得1≤i≤k,C_i= \sum\limits_{j=l} ^ r a_j^2 \leq m

输入格式

第一行有两个整数?n,k,表示小智需要背的单词数量和小智需要背完单词的天数。

第二行有?n?个整数?a_i,第?i?个整数表示第?i?个单词的「精神值」。

输出格式

共一行。

输出一个整数?m,表示小智所需的最小记忆力。

输入输出样例

输入?

5 1
1 2 3 4 5

输出?

55

输入?

4 2
1 2 3 4

输出?

16

说明/提示

样例 1 解释

由于小智最多要在 1 天内背完单词,所以必须将这些单词一次性背完,代价为?55。

样例 2 解释

可以发现,当小智第 1 天背?[1,3] 的单词,第 2 天背?[4,4]?的单词时需要的记忆力最少,为?4^2 = 16。

数据规模与约定

对于所有测试点,保证?1≤n≤1×105,1≤k≤n,1≤ai?≤1×106。

分析

题目要求我们找到最小的m,使得被划分的k个部分的Ci都小于等于m,那么理所当然大于m的所有数x同样满足这个条件,并且划分的组数t可能等于k,也有可能小于k;而小于m的数x划t一定会大于k,所以我们发现m这个答案存在单调性,那就可以使用二分方法来找m,而这个判断的标准就是划分的组数t大于k还是小于等于k,即使等于k也要考虑m再小一点能不能一样满足。

具体流程就是从左往右遍历数列,用sum记录当前组的和,如果下一个数加进来大于x,那么这个数就要另成一组。以这种方式确定x下的分组数k。

这里我们就知道一个数x对应了所分的组数t,我们要求的m就是当t=k时的最小x

Code

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 1e5 + 5;
typedef long long ll;

ll a[N];
int n, k;

bool check(ll x)
{
    ll t = 0;
    for (int i = 0; i < n; i++)
    {
        ll sum = a[i];
        while (i + 1 < n && sum + a[i + 1] <= x)
            sum += a[++i];
        if (++t > k)
            return false;
    }

    return true;
}

int main()
{
    cin >> n >> k;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
        a[i] *= a[i];
    }
    sort(a, a + n);

    ll l = a[n - 1];
    ll r = 1ll << 60;
    ll ans = 0;
    while (l <= r)
    {
        ll mid = (l + r) >> 1;
        if (check(mid))
        {
            ans = mid;
            r = mid - 1;
        }
        else
            l = mid + 1;
    }

    cout << ans << endl;
    return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:13:21  更:2022-03-15 22:18:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:39:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码