题面

题目大意:

给定一个 \(n\) , 所有军人的数量均在 \([1, n]\)

给定 \(a_i\) 代表高度为 \(i\) 的军人的个数

你要将这些军人分成 \(k\) 行, 满足下面两个条件

  • 每行人数相等
  • 同一行任意两个军人的高度差的绝对值不超过 1

问你最多能够选多少个军人分成 \(k\) 行

题解

题目满足单调性, 可以二分

我们二分一个 \(mid\) 表示每一行有 \(mid\) 个军人

不难证得首先将高度相等的分成一行, 再分高度不相等的是最优的

简要证明 : 可将不是上述方案的方案调整为是上述方案的方案, 结果不会更差

那么现在我们就是要看怎么分是最优的

我们将高度为 \(i + 1\) 的并到 \(i\) 上去等价于把 \(i\) 的并到 \(i + 1\) 上去

假如说 \(a_{i + 1} >= a_i \% mid\) , 我们就可以将 \(a_{i + 1}\) 减去 \(a_i \% mod\) , 再将 \(ans\) 加一

正确性:

首先如果不用 \(a_i\) 剩下的, 和这部分剩下的配对的 \(a_{i + 1}\) 肯定是要跟自己或者 \(a_{i + 2}\) 配对的

也就是说这一部分肯定是要用的, 如果用在自己和后面身上, 可能会导致后面的无法配对

也就是说

这一部分总会配对, 跟前面配对的不会对后面造成影响, 因为后面的总数没变

跟后面的配对可能会对后面的答案造成影响, 因为总数变了

由此可见这样配对不会更差

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
typedef long long ll;
const int N = 30005;
using namespace std; int T, n;
ll k, a[N], b[N], ans, sum; template < typename T >
inline T read()
{
T x = 0, w = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * w;
} bool check(ll x)
{
ll res = 0; b[1] = a[1];
for(int i = 1; i <= n; i++)
{
res += b[i] / x;
b[i + 1] = a[i + 1];
if(b[i + 1] >= x - (b[i] % x))
b[i + 1] -= x - (b[i] % x), res++;
}
return res >= k;
} int main()
{
T = read <int> ();
while(T--)
{
ans = sum = 0; n = read <int> (), k = read <ll> ();
for(int i = 1; i <= n; i++)
sum += (a[i] = read <ll> ());
a[n + 1] = 0;
ll l = 1, r = sum;
while(l <= r)
{
ll mid = (l + r) >> 1;
if(check(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
}
printf("%lld\n", 1ll * ans * k);
}
return 0;
}

最新文章

  1. 我读汤姆大叔的深入理解js(二)
  2. 用户Word写毕业论文时的文献引用方法
  3. python_way ,day22 tonardo
  4. SPOJ #442 Searching the Graph
  5. ASP.NET MVC实现多个按钮提交事件
  6. asp.net导入2013版本的excel问题解决
  7. Win2 Socket(套接字)相关 API
  8. android入门——Service
  9. Swift - 使用ALAssetsLibrary获取相簿里所有图片,视频(附样例)
  10. IBatis.net初步使用
  11. Essential C#读书笔记
  12. MBR区、DBR区、FAT区、DIR区和DATA区的区别
  13. Array 数组的排序 sort
  14. Xamarin打包
  15. Java实现打印日历的功能
  16. lightoj1234 打表技巧:分块打表
  17. linux系统虚拟机下安装nginx基础
  18. Chrome 开发者控制台中,你可能意想不到的功能
  19. [Python设计模式] 第13章 造小人——建造者模式
  20. .NET 同步与异步 之 线程安全的集合 (十一)

热门文章

  1. Abp 领域事件简单实践 &lt;四&gt; 聚合根的领域事件
  2. [书籍翻译] 《JavaScript并发编程》第六章 实用的并发
  3. Ajax的学习
  4. .tar.gz文件和.tar.xz文件的解压和压缩
  5. laravel 的安装与配置
  6. jmeter分布式压力测试配置操作
  7. json _ ajax_跨域
  8. c# 执行调用Oracle Procedure传参及回传值
  9. Linux学习笔记(九)shell基础:echo、命令别名和常用快捷键
  10. web页面长时间未操作自动退出登录