Product-sum numbers

A natural number, N, that can be written as the sum and product of a given set of at least two natural numbers, {a1, a2, … , ak} is called a product-sum number: N = a1 + a2 + … + ak = a1 × a2 × … × ak.

For example, 6 = 1 + 2 + 3 = 1 × 2 × 3.

For a given set of size, k, we shall call the smallest N with this property a minimal product-sum number. The minimal product-sum numbers for sets of size, k = 2, 3, 4, 5, and 6 are as follows.

k=2: 4 = 2 × 2 = 2 + 2
k=3: 6 = 1 × 2 × 3 = 1 + 2 + 3
k=4: 8 = 1 × 1 × 2 × 4 = 1 + 1 + 2 + 4
k=5: 8 = 1 × 1 × 2 × 2 × 2 = 1 + 1 + 2 + 2 + 2
k=6: 12 = 1 × 1 × 1 × 1 × 2 × 6 = 1 + 1 + 1 + 1 + 2 + 6

Hence for 2≤k≤6, the sum of all the minimal product-sum numbers is 4+6+8+12 = 30; note that 8 is only counted once in the sum.

In fact, as the complete set of minimal product-sum numbers for 2≤k≤12 is {4, 6, 8, 12, 15, 16}, the sum is 61.

What is the sum of all the minimal product-sum numbers for 2≤k≤12000?


积和数

若自然数N能够同时表示成一组至少两个自然数{a1, a2, … , ak}的积和和,也即N = a1 + a2 + … + ak = a1 × a2 × … × ak,则N被称为积和数。

例如,6是积和数,因为6 = 1 + 2 + 3 = 1 × 2 × 3。

给定集合的规模k,我们称满足上述性质的最小N值为最小积和数。当k = 2、3、4、5、6时,最小积和数如下所示:

k=2: 4 = 2 × 2 = 2 + 2
k=3: 6 = 1 × 2 × 3 = 1 + 2 + 3
k=4: 8 = 1 × 1 × 2 × 4 = 1 + 1 + 2 + 4
k=5: 8 = 1 × 1 × 2 × 2 × 2 = 1 + 1 + 2 + 2 + 2
k=6: 12 = 1 × 1 × 1 × 1 × 2 × 6 = 1 + 1 + 1 + 1 + 2 + 6

因此,对于2≤k≤6,所有的最小积和数的和为4+6+8+12 = 30;注意8只被计算了一次。

已知对于2≤k≤12,所有最小积和数构成的集合是{4, 6, 8, 12, 15, 16},这些数的和是61。

对于2≤k≤12000,所有最小积和数的和是多少?

解题

k个数的和 == k个数的积

求对应k时候最小的这个数

题目要求2≤k≤12000,时候的最小积数和的和

参考题解中的程序,详解程序注释

Java

package Level3;

import java.util.Set;
import java.util.TreeSet; public class PE088{
static void run(){
int Kmin = 2;
int Kmax = 12000;
int sum = 0;
Set<Integer> set = new TreeSet<Integer>();
for(int k=Kmin;k<=Kmax;k++){
int minN = getMin(k);
if(set.add(minN))
sum+=minN;
}
System.out.println(sum);
}
// 找出k对于最小的n
static int getMin(int k){
for(int n=k+1;;n++){
if(check(n,n,k))
return n;
}
}
// 一个数拆成成k个数的和或者k个数的积
// prod 乘
// sum 和
// 开始的时候这两个数是相等的 都是 prod 或者sum 拆分成k份 // 这里用到的是递归的方法,当 prod2 = prod1 * a ;sum2 = sum1- a
// 下面就可以检测下一轮了 check(prod2,sum2,k-1)
// 这里用递归也是因为可能出 8 = 2*2*2*1*1 = 2+2+2+1+1 的形式,乘子中有数相同 的情况
// 结束情况: 乘子是1的时候 sum == k k个1的和就是sum了
// k=1的时候 说明结束了 return prod == sum
// 下次递归可进行需要:d<= prod k-1<= sum-d 下面程序很显然的
static boolean check(int prod,int sum,int k){
if(sum <k) return false;
if(prod == 1) return sum==k;
if(k==1) return prod ==sum;
for(int d =2;d<= prod && sum-d>=k-1;d++){
if(prod%d==0){
if(check(prod/d,sum-d,k-1))
return true;
}
}
return false;
}
// 7587457
// running time=1s577ms
public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms"); }
}

参考链接

n[k]表示minimal product-sum numbers for size=k

n[k]的上界为2*k,因为2*k总是能分解成2*k,然后2*k=k+2+(1)*(k-2)

显然n[k]的下界为k

对于一个数num   因式分解后因子个数为product   这些因子的和为sump

则需要添加的1的个数为num-sump,所以size k=num-sump+product

===============================================

上面说的很好理解

在对于因式分解中

n[k] 是 一个数分解成k个数的和  、k个数的积的最小值

我上面链接中的程序的理解是通过因式分解,不断的缩小n[k]处的值,最终的值就是最小的,但是程序后面的递归理解不透。。。

# coding=gbk

import time as time
def run2():
kMax = 12000
n = [2*kMax for i in range(kMax)] def getpsn(num,sump,product,start):
k = num - sump + product
if k < kMax:
if num<n[k]:
n[k] = num
for i in range(start,kMax//num *2):
getpsn(num*i,sump+i,product + 1,i)
getpsn(1,1,1,2)
ans = sum(set(n[2:]))
print ans
#
# running time= 0.266000032425 s
def run():
kMin = 2
kMax = 12000
res=[]
for k in range(kMin,kMax+1):
minN = getMinN(k)
if minN not in res:
res.append(minN)
print sum(minN) def getMinN(k):
n = k + 1
while(True):
if check(n,n,k):
return n
n +=1 def check(prod,sum,k):
if sum<k : return False
if prod == 1:return sum==k
if k==1 :return prod ==sum
for d in range(2,prod):
if sum-d>=k-1 and prod%d ==0:
if check(prod/d,sum-d,k-1):
return True
return False t0 = time.time()
run2()
t1 = time.time()
print "running time=",(t1-t0),"s"

Project Euler 88:Product-sum numbers 积和数的更多相关文章

  1. Project Euler 42 Coded triangle numbers

    题意:三角形数序列的第n项由公式tn = 1/2n(n+1)给出:因此前十个三角形数是: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, - 将一个单词的每个字母分别转化为其 ...

  2. Project Euler 2 Even Fibonacci numbers

    题意:斐波那契数列中的每一项都是前两项的和.由1和2开始生成的斐波那契数列前10项为:1, 2, 3, 5, 8, 13, 21, 34, 55, 89, -考虑该斐波那契数列中不超过四百万的项,求其 ...

  3. Project Euler 345: Matrix Sum

    题目 思路: 将问题转化成最小费用流 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #incl ...

  4. Project Euler 13 Large sum

    题意:计算出以下一百个50位数的和的前十位数字. /************************************************************************* ...

  5. Python练习题 048:Project Euler 021:10000以内所有亲和数之和

    本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...

  6. Python练习题 034:Project Euler 006:和平方与平方和之差

    本题来自 Project Euler 第6题:https://projecteuler.net/problem=6 # Project Euler: Problem 6: Sum square dif ...

  7. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  8. Python练习题 032:Project Euler 004:最大的回文积

    本题来自 Project Euler 第4题:https://projecteuler.net/problem=4 # Project Euler: Problem 4: Largest palind ...

  9. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

随机推荐

  1. javascript 数字字符串转为数字

    var a="111"; comsole.log(a);     //打印出来是个字符串类型 comsole.log(+a);   //打印出来是个数字类型 comsole.log ...

  2. mongodb在ubuntu下的couldn‘t remove fs lock errno:9 Bad file descriptor的错误

    按照官网上的安装方法: 在ubuntu系统下有可能出现如下错误: couldn't remove fs lock errno:9 Bad file descriptor 此时需要修改文件所有者 $ s ...

  3. 使用tortoise git管理gitolite版本库

    gitolite-admin是用于管理git版本库的版本库,将其从服务器上clone下来. 使用tortoise git clone的时候需要指定私钥,私钥的格式是ppk的,需要使用putty的PUT ...

  4. Nginx+Tomcat动静分离

    需求:nginx处理用户请求的静态页面,tomcat处理用户请求jsp页面,来实现动态分离,nginx处理静态页面效率远高于tomcat,这样一来就能更好的提高并发,处理性能. 准备软件: 下载jdk ...

  5. Windows7鼠标右键里没有新建文本文件的选项,解决办法

    1.“开始”->“运行”,输入"regedit",打开注册表编辑器 2.展开HKEY_CLASSES_ROOT,找到.txt 3.选中.txt,查看右侧窗格的“默认值”是不是 ...

  6. Linux挂载60T存储

    操作系统: CentOS 6.3 存储:总大小为72T,并划分成3个块,每块20T 安装多实例MySQL数据库,不想挂载3个块,弄成一个大的比较方便管理,个人比较懒. 配置多路径:http://blo ...

  7. MVC学习系列——Model验证扩展

    MVC中,实现了前端后端的验证. 前端验证.步骤: web.config这两个得开启: <add key="ClientValidationEnabled" value=&q ...

  8. linux 命令grep

    linux 命令grep grep命令用来搜索文本,或从给定的文件中搜索行内包含了给定字符串或单词的文件.通常来说,grep显示匹配的行.使用grep来搜索包括一个或多个正则表达式匹配到的文本行,然后 ...

  9. SQL Server 2008导出数据为SQL脚本的操作步骤

    以前我们要将一个表中的数据导出为脚本,那么只有在网上找一个导出数据的Script,然后运行就可以导出数据脚本了.现在在SQL Server 2008的Management Studio中增加了一个新特 ...

  10. Python环境搭建和开发工具的配置

    本文转自http://237451446.blog.51cto.com/2307663/766781 因为要学习python了,第一步当然是环境搭建和开发工具的配置了,下边开始了. 我的开发环境是在w ...