晴天想把一个包含n个整数的序列a分成连续的若干段,且和最大的一段的值最小,但他有强迫症,分的段数不能超过m段,然后他就不会分了。。。他想问你这个分出来的和最大的一段的和最小值是多少?
在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Description晴天想把一个包含n个整数的序列a分成连续的若干段,且和最大的一段的值最小,但他有强迫症,分的段数不能超过m段,然后他就不会分了。。。他想问你这个分出来的和最大的一段的和最小值是多少? Input第一行输入一个整数t,代表有t组测试数据。 Output输出一个整数表示和最大的一段的最小值。 Sample Input1
3 2
1 3 5
Sample Output5
HINT
1 3 5 分成一段可以为1 3 5和为9,分成两段可以为1,3 5或者1 3,5,和最大的一段值分别为8,5,所以答案为5 说到底 自己的二分还是太渣
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<math.h> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 50009 int a[N],n,m; bool q(int x) { int s=0,t=0; for(int i=0;i<n;i++) { if(s+a[i]>x) ///判断以x为一段的最大值 能有几段 { t++; s=a[i]; if(t>=m) return false;///如果超过m段 则返回0 } else s+=a[i]; } return true;///当前的mid满足 } int main() { int T; scanf("%d",&T); while(T--) { int sum=0,maxx=0; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); maxx=max(maxx,a[i]); sum+=a[i]; } int l=maxx,r=sum,mid,ans;///我们所求的值一定在maxx与sum之间 这两个值就是短点值 从中选出最小的 while(l<=r) { mid=(l+r)/2; if(q(mid))///如果当前的mid值满足于分m段切最大值为mid 则ans等于mid提取出来 并缩小r 看看之前是否有更优的值 { ans=mid; r=mid-1; } else ///当前的值不满足 则加大数 l=mid+1; } printf("%d\n",ans); } return 0; } 前路弥漫 边走边看 |
2022-08-18
2022-08-17
2022-11-06
2022-08-17
2022-07-29
请发表评论