我想将一个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
更大,需要很长时间。我怎么能有效地做到这一点?
答案 0 :(得分:1)
从您的算法中,我可以看到您希望<p>mousedown me</p>
与x=a+b+c
。
显然,对于y = 3,我们有a<=b<=c
,然后1<=a<=x/3
,a<=b<=(x-a)/2
对于给定的y,我们得到:c=x-b-a
,1<=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]
会产生无法管理的数字或解决方案: - (