如何通过各种方式划分多个数字?

时间:2015-08-11 13:02:12

标签: java math

我想将一个x分成y个部分,我希望所有可能的配置都能做到这一点。我怎样才能有效地做到这一点? 例子x = 100,y = 3。我能做到这一点:

    int x = 100;
    for (int a = 1; a < x; a++) {
        for (int b = a; b < x; b++) {
            for (int c = b; c < x; c++) {
                if (a+b+c == x) {
                    //DO SOMETHING
                }
            }
        }
    }

我认为这样可行(如果我错了,请纠正我),但当然效率不高,因为我只想要if语句为真的情况。而且y更大,需要很长时间。我怎么能有效地做到这一点?

1 个答案:

答案 0 :(得分:1)

从您的算法中,我可以看到您希望<p>mousedown me</p>x=a+b+c

显然,对于y = 3,我们有a<=b<=c,然后1<=a<=x/3a<=b<=(x-a)/2

对于给定的y,我们得到:c=x-b-a1<=a1<=x/y,... a1<=a2<=(x-a1)/(y-1)

但是你需要一个任意y的解决方案,你需要一个递归算法。

这是一个java实现:

ai<=a(i+1)<=(x-a1-...-ai)/(y-i)

public void split(int number, int pieces) { total = 0; dosplit(number, pieces, new ArrayList<Integer>()); } private void dosplit(int number, int pieces, List<Integer> begin) { if (pieces == 1) { if (begin.isEmpty() || (number >= begin.get(begin.size() - 1))) { begin.add(number); total += 1; //DO SOMETHING WITH BEGIN begin.remove(begin.size() - 1); } } else { int start, end; start = (begin.isEmpty()) ? 1 : begin.get(begin.size() - 1); end = 1 + (1 + number - start)/pieces; for(int i=start; i<=end; i++) { begin.add(i); dosplit(number - i, pieces - 1, begin); begin.remove(begin.size() - 1); } } 正确地产生:

split(10,3)

尽可能少的无用步骤。

但是[1, 1, 8] [1, 2, 7] [1, 3, 6] [1, 4, 5] [2, 2, 6] [2, 3, 5] [2, 4, 4] [3, 3, 4] 会产生无法管理的数字或解决方案: - (