北大ACM POJ 1032题解

[原创]北大ACM POJ 1032题解

这道题找到规律了就很好写。

题意就是求N1+N2+...+Nn=N. 使N1 ,N2...Nn都不相等且他们的乘积最大

做法就是先求出以2为起始的最大连续自然数序列之和sum,使得sum的值不超过输入数n。
然后分情况讨论:

设此最大序列为2,3,...,i,则:

1.若剩余值(n-sum)等于i,则最后输出序列为:3,4,...,i,i+2,即将原最大序列每项加1,再将最后剩余的一个1加到最后一项上。

2.若剩余值(n-sum)小于i,则从序列的最大项i开始,从大到小依次将每项加1,直到剩余值用完。


简单说明下此规律:
首先说说连续,可以看到最后结果a[i]-a[i-1]<=2,也就是相邻两个数不能相差2以上,因为如果
a[i]-a[i-1]=3,那么显然a[i]-1,a[i-1]+1也是满足要求的,且它们之间的乘积大于原来的,因此当相邻两个数相差2以上时,
总可以找到它们之间的两个数使得结果是更优的。

再来说说该序列必须以2或3开始,若序列第一项为5,则5=2+3,而2*3>5使得结果更优,对于大于5的第一项有类似结果。
再考虑4为第一项,根据前面的第一条,那么第二项只能为5或6.对于4,5可以分解为2,3,4使得结果更优。而对于4,6可以分解为
2,3,5使得结果更优
。因此可以看到该序列不可能是以大于3为开始的。

规律就是这样了,代码如下:

Problem: 1032 User: absolute
Memory: 204K Time: 32MS
Language: C++ Result: Accepted

#include
<stdio.h>
int main()
{
int n,j;
scanf("%d",&n);
int i=2;
int sum=0;
while(sum+i<=n)
{
sum += i;
i++;
}
int diff = n-sum;
if(diff==i-1)
{
for(j=3;j<i;j++)
printf("%d ",j);
printf("%d\n",j+1);
}
else
{
for(j=2;j<i-diff;j++)
printf("%d ",j);
for(j=i-diff;j<i;j++)
printf("%d ",j+1);
printf("\n");
}
return 0;
}

你可能感兴趣的:(ACM)