加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 所有自然数,总和为N,反转总和为1

发布时间:2020-12-14 16:36:40 所属栏目:Java 来源:网络整理
导读:我有一个问题需要解决.给出了N个自然数.我需要找到一个自然数的列表,总和到给定的数字,同时反转到1. a + b + c + ... = N1/a + 1/b + 1/c + ... = 1 a,b,c不一定是唯一的. 我已经提出了Java中的以下代码.它适用于简单的情况,但对于N已经非常缓慢. 1000. 如何
我有一个问题需要解决.给出了N个自然数.我需要找到一个自然数的列表,总和到给定的数字,同时反转到1.
a + b + c + ... = N
1/a + 1/b + 1/c + ... = 1

a,b,c不一定是唯一的.

我已经提出了Java中的以下代码.它适用于简单的情况,但对于N>已经非常缓慢. 1000.

如何重写该方法,即使数百万的工作速度也很快?也许,我应该放弃递归,或者用我想念的数学技巧来切断一些分支?

SSCEE:

private final static double ONE = 1.00000001;

public List<Integer> search (int number) {
    int bound = (int)Math.sqrt(number) + 1;
    List<Integer> list = new ArrayList<Integer>(bound);

    if (number == 1) {
        list.add(1);
        return list;
    }

    for (int i = 2; i <= bound; i++) {
        list.clear();
        if (simulate(number,i,list,0.0)) break;
    }

    return list;
}


//TODO: how to reuse already calculated results?
private boolean search (int number,int n,List<Integer> list,double sum) {
    if (sum > ONE) {
        return false;
    }

    //would be larger anyway
    double minSum = sum + 1.0 / number;
    if (minSum > ONE) {
        return false;
    }

    if (n == 1) {
        if (minSum < 0.99999999) {
            return false;
        }

        list.add(number);
        return true;
    }

    boolean success = false;
    for (int i = 2; i < number; i++) {
        if (number - i > 0) {
            double tmpSum = sum + 1.0 / i;
            if (tmpSum > ONE) continue;

            list.add(i);
            success = search(number - i,n - 1,tmpSum);
            if (!success) {
                list.remove(list.size() - 1);
            }

            if (success) break;
        }
    }

    return success;
}

解决方法

论文 “A Theorem on Partitions”,1963 by Graham,R. L.显示,对于N> 77有一个解决方案,其中使用的数字是dinstinct,并提出一种算法来找到这样的分解.

算法如下:

>如果N小于333,则使用预计算表来获取结果.
>如果N是奇数,则为(N-179)/ 2找到分解d1,d2,d3,d4,…,dk,然后为3,7,78,91,2 * d1,2 * d2,2 * d3,2 * dk是N的分解
>如果N是偶数,则为(N-2)/ 2找到分解d1,然后找到2,2 * dk是N的分解

但是,由于您不关心在分解中具有不同的数字,因此可以将预计算结果的表的大小减小到60,并且在N为奇数的情况下,找到分解d1,(N-9)/ 2,那么3,6,2 * dk是N的分解

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读