呃,通过这题有深入的理解了一下二分查找的神奇。。。
题意是:给你n天和每天需要花的钱,让你把这些天分成m份,每份都是连续的一天或几天,要求每份的和尽量小,输出这个和。二分的上界为所以钱的总数,下界为每天所花钱的最大值,然后二分查找到最适合的mid。但是,却为此WA了无数次啊~~,悲催啊·····
恩,还是举个例子来说吧,10 10 3 10 4 1 9 6 8 8 10 5 6,这一组数据,如果你用二分的查找mid值的话,可能会输出13,但是这题的答案是14,因为你找不到一个整数正好符合搜索条件,但是如果是14的,最后的5和6可以是一组,也可以是两组,前面的其他的已经符合了,即,14的话,可以这样分组10 , 10 3 , 10 4, 1 9 , 6 8 , 8 , 10 , 5 6,也可以如下分组:10 , 10 3 , 10 4 ,1 9 ,6 8 , 8 , 10 , 5 ,6。而如果是13的话,最少的组数是10 ,10 3, 10, 4 1, 9, 6 , 8 ,8 ,10, 5 6 ,所以答案应该是14;
讲的不是很明白,可以看下我的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> int v[100005]; int main() { int n , m , s , e , mid , sx , x , i; while (scanf("%d%d",&n,&m) != EOF) { s = e = 0; for (i = 0; i < n ; i++) { scanf("%d", &v[i]); if (v[i] > s) s = v[i]; e += v[i]; } while (s < e) { mid = (s + e) / 2; x = 0;sx = 0; for (i = 0 ;i < n; i++) { x += v[i]; if(x > mid) { sx++; x = v[i]; } } if (sx < m) e = mid; else s = mid + 1; } printf ("%d\n", mid); } return 0; }