球球大作战
Posted fighting-sh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了球球大作战相关的知识,希望对你有一定的参考价值。
球球大作战
http://acm.hdu.edu.cn/contests/contest_showproblem.php?cid=831&pid=1003
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0
Problem Description
小Z最近迷上了球球大作战,他准备出一个与球球大作战相似的题目来考考大家。现在有n个球依次排列在一条直线上,每个球有其对应的体积。每次合并操作可以将任意相邻两个球合并为一个球,合并之后的球的体积为这两相邻球体积之和。现在有m次合并,经过这m次合并之后,希望剩下球中体积的最小值能够最大(采用最佳合并策略)。
Input
输入一个T,代表数据的组数。(T<=10)
第二行包含两个正整数N,M,表示N个球,M次合并机会。
接下来一行为n个正整数x[1], x[2], … ,x[n],其中x[i]表示编号为i的球的体积。
数据范围:1≤M<N≤100000,1≤x[i]≤100000。
第二行包含两个正整数N,M,表示N个球,M次合并机会。
接下来一行为n个正整数x[1], x[2], … ,x[n],其中x[i]表示编号为i的球的体积。
数据范围:1≤M<N≤100000,1≤x[i]≤100000。
Output
对于每个测试样例,输出一行,包含一个整数,m次合并之后的剩下的球的体积的最小值最大是多少。每个测试样例占一行。
Sample Input
2
4 2
4 2 3 5
6 3
1 7 2 2 5 9
Sample Output
6
8
Hint:
第一组样例:
合并4、2得到{ 6 3 5 },合并3、5得到{ 6 8 },最小值为6。
也可以这样进行合并,合并2、3得到{ 4 5 5 },合并4、5得到{ 9 5 },最小值为5,但最小值小于上面的合并方案。
第二组样例:
合并1、7得到 { 8 2 2 5 9 },合并2、2得到 { 8 4 5 9 },合并4、5得到 { 8 9 9 },最小值为8。
求最小值最大。。明显的二分题。
合并m次,可以看成把n个数分成n-m个区间
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<string> 6 #include<cstdio> 7 #include<cmath> 8 #include<map> 9 #define MAXN 1000005 10 #define INF 0x3f3f3f3f3f3f3f3f 11 using namespace std; 12 13 long long a[100005]; 14 long long Max; 15 int n; 16 int Check(long long s){ 17 int cnt=0; 18 long long sum=0; 19 for(int i=1;i<=n;i++){ 20 sum+=a[i]; 21 if(sum>=s){ 22 cnt++; 23 if(Max>sum) Max=sum; 24 sum=0; 25 } 26 } 27 return cnt; 28 } 29 30 int main(){ 31 std::ios::sync_with_stdio(false); 32 int T; 33 cin>>T; 34 while(T--){ 35 int m; 36 cin>>n>>m; 37 long long L=0,R=10000000005LL; 38 for(int i=1;i<=n;i++){ 39 cin>>a[i]; 40 } 41 long long mid; 42 long long ans; 43 while(L<=R){ 44 Max=INF; 45 mid=(L+R)/2; 46 if(Check(mid)<(n-m)){ 47 R=mid-1; 48 } 49 else{ 50 ans=Max; 51 L=mid+1; 52 } 53 } 54 cout<<ans<<endl; 55 } 56 57 }
以上是关于球球大作战的主要内容,如果未能解决你的问题,请参考以下文章