给定一个正整数n,将其分成m段,每段为n1,n2,...,nm,求怎么划分使得n1*n2*...*nm最大
2014-10-08 21:17
471 查看
题目:自然数N分解为n个自然数的和,求这n个数的乘积最大值
分析:最优问题,可以用动态规划求解
1、描述最优解结构
N = a1 + a2 + ... + an;
M = a1 * a2 * ... * an;
求M的最大值
考虑到N = a + b,而a与b又可以分解为另外几个和为a或b的数的积,因此对于确定的N = a + b,有一个最优解M(N) = M(a)*M(N-a)。而a又有1到N/2种取值,所以有一般最优解M(N) = max{M(a) + M(N - a)}(a < N/2)。而对于1、2、3、4、5等的M值列一个表,就可以得到N<=4时,M(N) = N。于是有下列递归定义。
2、递归定义最优解
3、按自底向上的方式计算最优解
源码:
分析:最优问题,可以用动态规划求解
1、描述最优解结构
N = a1 + a2 + ... + an;
M = a1 * a2 * ... * an;
求M的最大值
考虑到N = a + b,而a与b又可以分解为另外几个和为a或b的数的积,因此对于确定的N = a + b,有一个最优解M(N) = M(a)*M(N-a)。而a又有1到N/2种取值,所以有一般最优解M(N) = max{M(a) + M(N - a)}(a < N/2)。而对于1、2、3、4、5等的M值列一个表,就可以得到N<=4时,M(N) = N。于是有下列递归定义。
2、递归定义最优解
3、按自底向上的方式计算最优解
源码:
#include <iostream> #include <fstream> #include <math.h> using namespace std; #define SIZE 1000 unsigned long m[SIZE], t[SIZE]; //m[i]存放和为i的数的乘积最大值,t[i]存放使m[i]为最大时,将i划分为2部分的j的值,即m[i]=m[j]*m[i-j]最大时j的值 void mt(int a) { int i, j; for (i = 0; i < SIZE; i++) //m、t初始化 { m[i] = i; t[i] = i; } for (i = 4; i <= a; i++) //按自底向上来得到m与t的值 { for (j = 2; j <= i/2; j++) { if (m[i] <= m[j] * m[i - j]) { m[i] = m[j] * m[i - j]; t[i] = j; } } } } void printt(int a) //打印和为a,积最大的所有数 { int k; k = t[a]; //k为a的第一次分解值 if (k == t[k]) //不能再分的时候,输出k { cout<<k; } else //继续分解,打印出和为k,积最大的所有数 { printt(k); } if(a - k > 0) //打印出和为a - k,积最大的所有数 { cout<<" * "; printt(a - k); } } void main() { int n; cout<<"input a number(<= 62) "; //输入小于62的数。由于unsigned long只能表示到2的31次方,只能存储小于62的M值 cin>>n; mt(n); //计算m和t cout<<m <<" = "; printt(n); //打印 cout<<endl; }
相关文章推荐
- 给定一个单向链表L(N0,N1,N2,N3……),在不改变node值得情况下,来编程实现对链表重新排列 ,使得排序后的链表为(N0,Nn,n1,Nn-1,n2,Nn-2……)。
- 任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
- 给定一个正整数数组,找所有元素组合起来最大的值(答案)
- 给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大
- 给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大 java实现
- 给定一个正整数n,则在n所有的分解式中,求因子乘积最大的一个分解及此乘积。
- 程序员面试金典——解题总结: 9.18高难度题 18.12给定一个正整数和负整数组成的N*M矩阵,编写代码找出元素总和最大的子矩阵。
- 给定一个正整数数组求组合起来的最大值
- 一道题:给定一整数序列A1,A2,...,An(可能有负数),求A1到An的一个自序列,使得Ai到Aj的和最大。例如:整数序列-2,11,-4,13,-5,2,-5,-3,12,-9的最大子序列为21
- 给定一个正整数和负整数组成的N*N矩阵,编写代码找出元素总和最大的子矩阵。
- HDU 1024 Max Sum Plus Plus(动态规划,给定一个数组,求其分成m个不相交子段和最大值的问题)
- 给定一个数组,当中有正负数,求当中的一段“子数组”(即任意长度,连续的数字), 使得这个“子数组”的和是所有“子数组”和中最大的
- 给定一个由非负整数和整数m组成的数组,可以将该数组分成m个非空的连续子数组。 写一个算法来最小化这些m个子阵列之间的最大和。
- 给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
- Java给定一个数组,数组元素是一些正整数,求这些正整数收尾详解得出的最大数或最小数
- HDU 1024 给定一个数组,求其分成m个不相交子段和最大值
- 一个只由字母数字字符和破折号组成的字符串S. 该字符串被N个破折号分成N + 1个组。 给定数字K,使得每个组包含完全K个字符,除了第一个组可能少于K
- HDU 1024 Max Sum Plus Plus(动态规划,给定一个数组,求其分成m个不订交子段和最大值的题目)
- 一个正整数n被分成若干个不同自然数的和,求组成n的一组自然数的最大乘积
- 给定一个正整数x,找到一个最小的正整数y,使得y的每一位相乘,最后值等于x