project euler 106

来源:互联网 发布:ios软件历史版本 编辑:程序博客网 时间:2024/06/16 22:28

Problem 106


Special subset sums: meta-testing

Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:

  1. S(B) ≠ S(C); that is, sums of subsets cannot be equal.
  2. If B contains more elements than C then S(B) > S(C).

For this problem we shall assume that a given set contains n strictly increasing elements and it already satisfies the second rule.

Surprisingly, out of the 25 possible subset pairs that can be obtained from a set for which n = 4, only 1 of these pairs need to be tested for equality (first rule). Similarly, when n = 7, only 70 out of the 966 subset pairs need to be tested.

For n = 12, how many of the 261625 subset pairs that can be obtained need to be tested for equality?

NOTE: This problem is related to Problem 103 and Problem 105.


特殊的子集和:元检验

记S(A)是大小为n的集合A中所有元素的和。若任取A的任意两个非空且不相交的子集B和C都满足下列条件,我们称A是一个特殊的和集:

  1. S(B) ≠ S(C);也就是说,任意子集的和不相同。
  2. 如果B中的元素比C多,则S(B) > S(C)。

在这个问题中我们假定集合中包含有n个严格单调递增的元素,并且已知其满足第二个条件。

令人惊奇的是,当n = 4时,在所有可能的25组子集对中只有1组需要检验子集和是否相等(第一个条件)。同样地,当n = 7时,在所有可能的966组子集对中只有70组需要检验。

当n = 12时,在所有可能的261625组子集对中有多少组需要检验?

注意:此题和第103题及第105题有关。

package projecteuler;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Set;import junit.framework.TestCase;public class Prj106 extends TestCase {/** * [a1,a2,a3....,b1,b2,b3...]  * array a and b has same size. * [a1,a2,a3,...]; * [b1,b2,b3,...] * remove * a1 < b1 && a2 < b2 && a3 < b3 .... */public void testSpecialSubsetSumsMetaTesting() {int count = 0;int n = 12;for (int i = 2; i <= n / 2; i++) {int size = i;int[] arr = new int[2 * size];dfs(arr, 0, size, n);count += (C_n_p(n, size) * C_n_p(n - size, size) / 2 - resultList.size());resultList.clear();}System.out.println("count=" + count);}List<int[]> resultList = new ArrayList<int[]>();public void dfs(int[] arr, int id, int size, int n) {assert (arr.length == 2 * size);if (id >= size) {printArr(arr);resultList.add(Arrays.copyOf(arr, arr.length));return;}for (int i = 1; i <= n; i++) {if (id == 0) {arr[id] = i;for (int j = i + 1; j <= n; j++) {arr[id + size] = j;dfs(arr, id + 1, size, n);}} else {if (i <= arr[id - 1]) {continue;}Set<Integer> set = new HashSet<Integer>();for (int k = 0; k < id; k++) {assert (arr[k] != arr[k + size]);set.add(arr[k]);set.add(arr[k + size]);}if (set.contains(i)) {continue;}arr[id] = i;set.add(i);for (int j = i + 1; j <= n; j++) {if (set.contains(j) || arr[id + size - 1] >= j) {continue;}arr[id + size] = j;dfs(arr, id + 1, size, n);}}}}void printArr(int[] diff) {for (int i = 0; i < diff.length; i++) {System.out.print(diff[i] + "\t,");}System.out.println();}long C_n_p(long n, long p) {long up = 1;long low = 1;long i = 1L;while (i <= p) {up *= (n + 1L - i);low *= i;i++;}return up / low;}}


0 0
原创粉丝点击