分石子问题简易题解

有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 }

 

 

你可能感兴趣的:(题解)