有N个石子,每个石子重量Qi;按顺序将它们装进K个筐中;求一种方案,使得最重的筐最轻。
样例:
N=9,K=3
9 7 5 6 8 4 3 2 7
16 19 16
最轻的最重筐为19
思路:
二分搜索(PS:这就是传说中的“二分答案”?)
IOI中国国家集训队2005论文《参数搜索的应用》中有详细分析,这里我就不多说了,下面是我的代码。
1 //2011.11.06 2 //By LYLtim 3 4 #include<stdio.h> 5 #include<stdlib.h> 6 7 size_t N, K; 8 unsigned *Q, sum; 9 10 void Init(void) 11 { 12 size_t i; 13 scanf("%lu %lu", &N, &K); 14 Q = malloc(sizeof(unsigned)*N); 15 for(i = 0; i < N; i++) { 16 scanf("%u", &Q[i]); 17 sum += Q[i]; 18 } 19 } 20 21 char Can(unsigned P) 22 { 23 unsigned *Basket; 24 size_t i, nB = 0; 25 Basket = (unsigned *) calloc(K, sizeof(unsigned)); 26 for (i = 0; i < N; i++) { 27 if (Basket[nB] + Q[i] <= P) 28 Basket[nB] += Q[i]; 29 else { 30 if (nB == K - 1) //begin from 0, full. 31 return 0; 32 Basket[++nB] = Q[i]; 33 } 34 } 35 free(Basket); 36 return 1; 37 } 38 39 unsigned Search(void) 40 { 41 int start = Q[0], end = sum; 42 while (start <= end) { 43 unsigned m = (start + end) >> 1; 44 if (Can(m)) 45 end = m - 1; 46 else 47 start = m + 1; 48 } 49 free(Q); 50 return start; 51 } 52 53 int main(void) 54 { 55 Init(); 56 printf("%u", Search()); 57 return 0; 58 }