子序列最大和
2016-08-17 17:09
99 查看
1919: D
Time Limit: 1 Sec Memory Limit:128 MB
Submit: 167 Solved: 35
SubmitStatusWeb
Board
Description
晴天想把一个包含n个整数的序列a分成连续的若干段,且和最大的一段的值最小,但他有强迫症,分的段数不能超过m段,然后他就不会分了。。。他想问你这个分出来的和最大的一段的和最小值是多少?Input
第一行输入一个整数t,代表有t组测试数据。每组数据第一行为两个整数n,m分别代表序列的长度和最多可分的段数。
接下来一行包含n个整数表示序列。
0<=n<=50000 1<=m<=n,0<=ai<=10000。
Output
输出一个整数表示和最大的一段的最小值。Sample Input
1 3 2 1 3 5
Sample Output
5
HINT
1 3 5 分成一段可以为1 3 5和为9,分成两段可以为1,3 5或者1 3,5,和最大的一段值分别为8,5,所以答案为5二分最小值,然后验证贪心验证,即若当前最小值是mid,那从第一个数开始累加,每次累加到大于mid时就分成新的一段继续累加,最后判断有多少段。
#include<cstdio> #include<algorithm> using namespace std; int a[50005]; int n,m; bool judge(int mid) { int s=0,cot=0; for(int i=1;i<=n;i++) { if(mid<a[i])//偏小 return false; if(mid>=s+a[i]) s+=a[i]; else { s=a[i];//开始下一个子序列 cot++;//子序列数 if(cot>m-1) return false; } } return true; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int maxm=0,sum=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); maxm=max(a[i],maxm); sum+=a[i]; } int mid; int l=maxm,r=sum; while(l<r) { mid=(l+r)/2;//二分查找 if(judge(mid)) r=mid; else l=mid+1; } printf("%d\n",l); } return 0; } /************************************************************** Problem: 1919 User: wry Language: C++ Result: Accepted Time:76 ms Memory:1068 kb ****************************************************************/
相关文章推荐
- 100题_03 最大子序列和
- 最大连续子序列
- hdu 1231 最大连续子序列
- NYOJ - 745 - 蚂蚁的难题(二)(最大子序列和变形,动态规划)
- Max Sum Plus Plus m段连续子序列最大和
- 最大子序列和问题的解——C++实现;
- HDU-#1003 Max Sum(DP+区间最大子序列)
- 【网络流24题】 No.6 最长不减子序列问题 (最大流)[模型:最多不相交路径]
- Hdu 1231 最大连续子序列
- 最大连续子序列和:动态规划经典题目(2)
- 最大子序列
- hdu 1231 最大连续子序列 ,1003 Max Sum;
- hdu1003求最大和子序列
- 九度OJ-题目1011 最大连续子序列
- 题目1011:最大连续子序列
- 连续子序列内各元素和的最大值
- hdu 1087 上升子序列最大和
- HDU 1231 最大连续子序列 简单dp
- 最大子序列的三种求解方式
- 动态规划--最大连续子序列