洛谷 P1182 数列分段 Section II
2024-09-04 12:30:41
洛谷 P1182 数列分段 Section II
题目描述
对于给定的一个长度为N的正整数数列A-iA−i,现要将其分成M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小。
关于最大值最小:
例如一数列4 2 4 5 142451要分成33段
将其如下分段:
[4 2][4 5][1][42][45][1]
第一段和为66,第22段和为99,第33段和为11,和最大值为99。
将其如下分段:
[4][2 4][5 1][4][24][51]
第一段和为44,第22段和为66,第33段和为66,和最大值为66。
并且无论如何分段,最大值不会小于66。
所以可以得到要将数列4 2 4 5 142451要分成33段,每段和的最大值最小为66。
输入格式
第11行包含两个正整数N,M。
第22行包含NN个空格隔开的非负整数A_iA**i,含义如题目所述。
输出格式
一个正整数,即每段和最大值最小为多少。
输入输出样例
输入 #1复制
输出 #1复制
说明/提示
对于20%20%的数据,有N≤10N≤10;
对于40%40%的数据,有N≤1000N≤1000;
对于100%100%的数据,有N≤100000,M≤N, A_iN≤100000,M≤N,A**i之和不超过10^9109。
题解:
这题其实说的就是数学化了一点,其实实现的时候和P2882和JDOJ 2225是一样的,(就是原题原代码),我JDOJ 2225讲解的详细一点,所以就用JDOJ 2225的题解来看吧。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int n,m,cnt,tot;
int l,r,ll,rr;
int a[maxn];
bool check(int x)
{
tot=0;cnt=0;
for(int i=1;i<=n;i++)
{
if(tot+a[i]<=x)
{
tot+=a[i];
continue;
}
tot=a[i];
cnt++;
}
if(tot>0)
cnt++;
if(cnt<=m)
return 1;
else
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
ll=max(ll,a[i]);
rr+=a[i];
}
l=ll;r=rr;
while(l<r)
{
int mid=(l+r)/2;
if(check(mid))//二分的答案域表示领到工资最多的那一次最小的工资额
r=mid;
else
l=mid+1;
}
printf("%d",l);
return 0;
}
最新文章
- 高性能 Socket 组件 HP-Socket v3.2.1 正式发布
- Businessworks的设计思想
- delphi 获取图片某一像素的颜色值
- Scala 深入浅出实战经典 第48讲:Scala类型约束代码实战及其在Spark中的应用源码解析
- android使用微软雅黑字体
- Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数
- Codeforces 633D
- 非root模式下安装mysql
- 通过两个GPS计算两个GPS点的距离
- HDU 3294 (Manacher) Girls&#39; research
- SqlServer刷新所有视图
- UVa 127 - ";Accordian"; Patience
- 9.7寸RK3188瑞芯微四核爱立顺M33平板电脑 - 深圳吉祥星晨科技有限公司 - 华强商情网
- postgresql 在linux上的源码安装
- Python——网络爬虫
- python调用metasploit里的MS-17-010模块进行漏洞攻击
- Azure Powershell获取指定订阅下的虚拟机信息(ARM)
- opencv图像融合(大头)
- HTML meta头部小结
- 51nod1237 最大公约数之和 V3