| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
求一个区间内的最优解,二分+边界条件是关键题目的意思是将一组N个数据分成M个连续的包,要求每个包容量的最小值
如果分成1份的话,这个包的容量就是所有数据之和SUM
如果分成N份的话,这个包的容量就是N个数字中的最大元素MAX
于是我们要求的就是[MAX,SUM]中某一值K,二分搜索之
搜索条件为:
K可以让数组N分成M份(用K去划分数组时,得到的份数<=M)
K-1不可以让数组N分成M份(用K-1去划分数组时,得到的份数>M)
/**
*POJ-3273
*/
#include <iostream>
#include "stdio.h"
using namespace std;
int max_f(int nums[],int len){
int max=nums[0];
for(int i=1; i<len; i++){
max=max>nums[i]?max:nums[i];
}
return max;
}
int sum_f(int nums[],int len){
int sum=0;
for(int i=0; i<len; i++)
sum+=nums[i];
return sum;
}
int mid_f(int min,int max){
return (min+max)/2;
}
int part_f(int nums[],int value,int len){
int count=1,sum=nums[0];
for(int i=1; i<len; i++){
if(value<nums[i])
return -1;
sum+=nums[i];
if(sum>value){
count++;
sum=nums[i];
}
//printf("-->%d\n", count);
}
return count;
}
int main(){
int len=7,part=3;
scanf("%d %d",&len,&part);
int nums[len];
for(int i=0; i<len; i++){
scanf("%d",&nums[i]);
}
int max,min,mid,count=0;
min=max_f(nums,len);
max=sum_f(nums,len)+1;
mid=mid_f(min,max);
//printf("***%d %d %d\n", min,max,mid);
int part_now=part_f(nums,mid,len);
int part_now_l=part_f(nums,mid-1,len);
while(!(part_now<=part && (part_now_l>part || part_now_l==-1)) && count<100) {
//printf("-->%d %d %d %d %d\n", part_now, mid,min,max,part_f(nums,mid-1,len));
if(part_now>part){ //目前分的比较多,需要扩大单个容量
min=mid_f(min,max);
}else{ //目前分的比较少,有精简的余地,或者目前已经达标,尝试进一步精简
max=mid_f(min,max);
}
mid=mid_f(min,max);
part_now=part_f(nums,mid,len);
part_now_l=part_f(nums,mid-1,len);
count++;
}
printf("%d\n",mid);
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator