1 <?php
 2     /**
 3     *一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
 4     *比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
 5     *{3,6}{2,4,3} m=2
 6     *{3,3}{2,4}{6} m=3 所以m 的最大值为3
 7     **/
 8 
 9     #解题思路
10     #首先m必须满足两个条件
11     #1. 1<=m<=n
12     #2. sum(a) % m = 0,即sum(a)必须是m的倍数,其中a为待切分数组
13     #解题步骤:
14     #1. m从n开始,依次减小
15     #2. 判断m是否能满足题目条件,如满足,则返回m以及分组信息
16     #对于判断m是否能满足条件,使用辅助数组group_info[]
17     #其中group_info[i]=k表示a[i]被分配到第k组
18 
19     function maxm($a) {
20         $len = count($a);
21         $asum = 0;
22         for ($i = 0; $i < $len; $i++) $asum += $a[$i];
23 
24         #
25         for ($m = $len; $m >= 2; $m--) {
26             if ($asum % $m != 0) continue;
27             $group_info = array(); #分组信息
28             for ($i = 0; $i < $len; $i++) $group_info[$i] = 0;
29             if (test($a, $m, $asum, $group_info, $asum / $m, 1)) 
30                 return array("m" => $m, "group_info" => $group_info);
31         }
32 
33         return array("m"=> 1);
34     }
35 
36     function test($a, $m, $asum, &$group_info, $goal, $group_id) {
37         $len = count($a);
38         $msum = $asum / $m;
39 
40         if ($goal == 0) {
41             $group_id++;
42             $goal = $msum;
43             #所有分组分配结束
44             if ($group_id == $m + 1) return true;
45         } else if ($goal < 0) {
46             return false;
47         }
48         #将数组分组,并判断是否能满足条件
49         for ($i = 0; $i < $len; $i++) {
50             #跳过已分配元素
51             if ($group_info[$i] != 0) continue;
52             $group_info[$i] = $group_id;
53             #分配完a[i]继续往下分配
54             if (test($a, $m, $asum, $group_info, $goal - $a[$i], $group_id)) return true;
55             #a[i]分配失败,重新置为0
56             $group_info[$i] = 0;
57         }
58 
59         return false;
60     }
61 
62     $a = array(3, 2, 4, 3, 6, 2, 2, 2);
63     print_r(maxm($a));
64 ?>
posted on 2012-10-07 19:47  ZimZz  阅读(2441)  评论(0编辑  收藏  举报