有两种方法求解,(1)递归分解,这种方法很好想,但是超时
(2)分析题目,得出一些基本规律。(参考了他人的想法)
1, a[1] > 1
Proof: If a[1] = 1, a[t] could be replacedby a[t] + 1 and a[t]+1 > a[t] * 1.
2, 1 <= a[i+1] – a[i] <= 2
Proof: If exists i make a[i+1] – a[i] >2, then a[i], a[i+1] could be replaced by a[i]+1, a[i+1]-1 together, and (a[i]+1)*(a[i+1] – 1) = a[i]*a[i+1] + a[i+1] – a[i] – 1 > a[i]*a[i+1]+1 >a[i]* a[i+1].
3, at most one i makes a[i+1] – a[i] = 2;
Proof: If i < j and a[i+1] – a[i] = 2,a[j+1] – a[j] = 2 then a[i], a[j+1] could be replaced by a[i]+1, a[j+1]-1 and (a[i] + 1)*(a[j+1] - 1 ) = a[i]*a[j+1] + a[j + 1] – a[i]-1. Case 1, i+1 = j, then (a[i] +1)*(a[j+1] - 1 ) = a[i]*a[j+1] + 3; Case 2, i + 1 <j, then (a[i] + 1)*(a[j+1] - 1 ) > a[i]*a[j+1] + 3.
4, a[1] <=3.
Proof: if a1>=4, then a1, a2 together could bereplaced by 2, a1-1, a2-1 together.
因此可以轻松构造出该序列:
#include <iostream>
#include <cstdio>
using namespace std;
int a[110];//存放拆分的数
int result[110];//存放结果
long long maxproduct;
int index = 1;
void rsplit(long long product,int begin)
{
int k = a[begin];
int s1,s2,i,j;
long long p;
for (j = 1; j <= k/2; ++j)
{
s1 = a[begin-1]+j;
s2 = k - s1;
if(s2 <= s1)return;
a[begin] = s1;
a[begin+1] = s2;
p = product*s1*s2;
if(maxproduct < p)
{
for (i = 1; i <= begin+1; ++i)
result[i] = a[i];
maxproduct = p;
index = begin+1;
}
rsplit(p/s2,begin+1);
}
}
void split(int N)
{
int n,i=2, m=0,j;
n = N;
while(m<n)
m += i++;
j = m-n;
m = 2;
if(j == 1)
{
m = 3;
j = i-1;
i++;
}
while(m < i-1)
{
if (m!=j)
printf("%d ",m);
m++;
}
printf("%d\n",i-1);
}
int main()
{
freopen("in.txt", "rt", stdin);
cin>>a[1];
maxproduct=0;
result[1] = a[1];
//split(1,1);
split(a[1]);
/* for (int i = 1; i <= index; ++i)
cout<<result[i]<<" ";
cout<<endl;*/
}