这是一个二分穷举问题,通过二分寻找最小值,不断枚举,但一定要二分结束,否则只要找到m组就结束,不一定是最优解。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn=100000+10; int a[maxn]; int m,n; bool judge(int mid) { int g=1,sum=0; for(int i=1;i<=n;i++) { if(sum+a[i]<=mid) sum+=a[i]; else {sum=a[i],g++;}//一组总和大于mid,重新分组,组数加一 } if(g<=m) return true; else return false; } int main() { int r=0,l=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(l<a[i]) l=a[i];//记录max,最为二分最左边的值,因为分组后的最小值必定大于单个的最大值 r+=a[i];//取总和作为最右边的值 } int mid; while(l<r) { mid=(l+r)/2;//此处的mid就是一组的最大值 if(judge(mid)) r=mid-1;//能找到<=m组,去取更小的右边界,看能不能找到更小的mid else l=mid+1;//超过m组,扩大左边界,找够m组 } printf("%d\n",mid); return 0; }
时间: 2024-10-29 19:11:50