把一个包含n个正整数的序列划分成m个连续的子序列(每个正整数恰好属于一个序列)。设第i个序列的各数之和为S(i),你的任务是让所有S(i)的最大值尽量小。
例如序列1 2 3 2 5 4 划分成3个序列的最优方案为1 2 3| 2 5| 4,其中S(1)、S(2),S(3)分别为6、7、4最大值为7;
如果划分成1 2 |3 2| 5 4, 则最大值为9,不如刚才好。n <= 10^6 ,所有数之和不超过10^9。#include <cstdio> #include <iostream> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <stack> #include <queue> #include <map> #include <set> #include <tgmath.h> using namespace std; int n,k; int s[20],s1[20]; bool calcu(int x) { int num = 0; int sum = 0; for(int i = 0;i<n;i++) { if(s[i]>x) { return false; } if(sum+s[i]>x) { s1[i-1] = 1; sum = s[i]; num++; if(num > k-1) return false; } else { sum+=s[i]; } } return true; } int main() { int num; while(scanf("%d%d",&n,&k)!=EOF) { int y = 0; for(int i=0;i<n;i++) { scanf("%d",&s[i]); y+=s[i]; } int x = 0; while(y>x) { memset(s1,0,sizeof(s1)); num = x+(y-x)/2; if(calcu(num)) y = num; else x = num+1; } for(int i = 0;i< n;i++) { if(s1[i] == 1) printf("%d | ",s[i]); else printf("%d ",s[i]); } printf("\n"); } }
最大值最小化 二分查找
最新推荐文章于 2023-05-19 21:52:47 发布