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