南邮 OJ 1271 最优分解问题

最优分解问题

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 77            测试通过 : 18 

比赛描述

n是一个正整数。现在要求将n分解为若干个互不相同的自然数和,且使这些自然数的乘积最大。

对于给定的正整数n,编程计算最优分解方案。



输入

文件的第行是正整数n

输出

程序运行结束时,将计算出的最大乘积输出。

样例输入

10

样例输出

30

提示

undefined

题目来源

NUAA




/* 要求互补相同
// Wrong Answer at Test 1
#include<iostream>
int main(){
	int n,i,j;
	scanf("%d",&n);
	__int64 *dp=new __int64[n+1],maxVal,temp;
	dp[1] = 1;
	for(i=2;i<=n;i++){
		maxVal = i;
		for(j=1;(j<<1)<=i;j++){
			if(maxVal < (temp=dp[j]*dp[i-j])){
				maxVal = temp;
			}
		}
		dp[i] = maxVal;
	}
	printf("%I64d\n",dp[n]);
}
*/


/* WA 2
#include<iostream>
#define MAX_N 10000
int a[MAX_N];
int result[MAX_N];

int main(){
	int n,i,k,len,j;
	scanf("%d",&n);
	k = 0;
	if(n<3){
		a[k++] = 0;
	}else if(n<5){
		a[k++] = 1;
		a[k++] = n-1;
	}else{
		a[k++] = 2;
		n -= 2;
		while(n>a[k-1]){
			a[k] = a[k-1]+1;
			n -= a[k];
			k++;
		}
		if(n==a[k-1]){
			a[k-1]++;
			n--;
		}
		for(i=0;i<n;i++){
			a[k-1-i]++;
		}
	}
	result[0] = len = 1;
	for(i=0;i<k;i++){
		for(j=0;j<len;j++){
			result[j] *= a[i];
		}
		for(j=0;j<n;j++){					//WA
			result[j+1] += result[j]/10;
			result[j] %= 10;
		}
		while(result[len]){
			result[len+1] = result[len]/10;
			result[len] %= 10;
			len++;
		}
	}
	for(i=len-1;i>=0;i--){
		printf("%d",result[i]);
	}
	printf("\n");
}

*/



/*
// AC 8MS
#include<iostream>
#define MAX_N 10000
int a[MAX_N];
int result[MAX_N];

int main(){
	int n,i,k,len,j;
	scanf("%d",&n);
	k = 0;
	if(n<3){
		a[k++] = 0;
	}else if(n<5){
		a[k++] = 1;
		a[k++] = n-1;
	}else{
		a[k++] = 2;
		n -= 2;
		while(n>a[k-1]){
			a[k] = a[k-1]+1;
			n -= a[k];
			k++;
		}
		if(n==a[k-1]){
			a[k-1]++;
			n--;
		}
		for(i=0;i<n;i++){
			a[k-1-i]++;
		}
	}
	result[0] = len = 1;
	for(i=0;i<k;i++){
		for(j=0;j<len;j++){
			result[j] *= a[i];
		}
		for(j=0;j<len;j++){
			result[j+1] += result[j]/10;
			result[j] %= 10;
		}
		while(result[len]){
			result[len+1] = result[len]/10;
			result[len] %= 10;
			len++;
		}
	}
	for(i=len-1;i>=0;i--){
		printf("%d",result[i]);
	}
	printf("\n");
}
*/



#include<iostream>
#define MAX_N 2000
#define LIMIT 1000
int a[MAX_N];
int result[MAX_N];

int main(){
	int n,i,k,len,j;
	scanf("%d",&n);
	k = 0;
	if(n<3){
		a[k++] = 0;
	}else if(n<5){
		a[k++] = 1;
		a[k++] = n-1;
	}else{
		a[k++] = 2;
		n -= 2;
		while(n>a[k-1]){
			a[k] = a[k-1]+1;
			n -= a[k];
			k++;
		}
		if(n==a[k-1]){
			a[k-1]++;
			n--;
		}
		for(i=0;i<n;i++){
			a[k-1-i]++;
		}
	}
	result[0] = len = 1;
	for(i=0;i<k;i++){
		for(j=0;j<len;j++){
			result[j] *= a[i];
		}
		for(j=0;j<len;j++){
			result[j+1] += result[j]/LIMIT;
			result[j] %= LIMIT;
		}
		while(result[len]){
			result[len+1] = result[len]/LIMIT;
			result[len] %= LIMIT;
			len++;
		}
	}
	printf("%d",result[len-1]);
	for(i=len-2;i>=0;i--){
		for(k=LIMIT/10;k;k/=10){
			printf("%d",result[i]/k);
			result[i] %= k;
		}
	}
	printf("\n");
}






你可能感兴趣的:(ACM,南邮OJ,最优分解问题)