1. 程式人生 > >給定一個正整數n,將其分成m段,每段為n1,n2,...,nm,求怎麼劃分使得n1*n2*...*nm最大

給定一個正整數n,將其分成m段,每段為n1,n2,...,nm,求怎麼劃分使得n1*n2*...*nm最大

#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[n]<<" = ";
	printt(n);                        //列印
	cout<<endl;
}