最优分解问题
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 77 测试通过 : 18
总提交 : 77 测试通过 : 18
比赛描述
设n是一个正整数。现在要求将n分解为若干个互不相同的自然数和,且使这些自然数的乘积最大。
对于给定的正整数n,编程计算最优分解方案。
输入
文件的第1 行是正整数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");
}