题解 P1249 【最大乘积】
NKU_AI_HMX · · 题解
不知道大家看其他的题解有没有产生很多问号???
(本题解修改了一些第一次提交发现的错误,感谢yhm12345同学指出。)
我来帮大家理清一下这题的思路,并对其他题解做出解释和补充(我之前看的时候也比较懵)。
以下是本题的主要思路:
大家都清楚这题的意思,我们尽可能的把n分成更多份(都大于1)那样乘积最大。 (这里讲一下如果分出来的数可以重复,那么有时候并不是分出的份数越多越大,比如6,分成2,2,2不如分成3,3。但是不能重复的话就不存在这样的情况,大家可以想一下。) 以“6”为例,我们可以想到,我们先分出来一个2,然后再分出一个3......但是这样面临一个问题:“最后有余数怎么办”,比如“8”;分出来2,3还剩下3,没法再分出4,这时候怎么办呢?有的同学会想我把余数3都加到3身上,我们就分成了2和6,但是这样是最大的吗?(3和5才是最大的) 这时候我补充一下有一篇题解中所说:
“把余数分到大的数上比分到小的数上得到的乘积更大”。
实际不太准确,我们很容易证明出来如果能把数分到更小的数上,那么乘积更大(大家可以想想)。但是为什么最终是分到了大的数呢?就好比把6分成2,4,按照我们刚才的分法,先分出来了2和3最后余1,理论上我们把1给2得到的结果更大,但是我们不允许数重复,所以我们需要先把1给3,这样如果还剩下余数的话就分给2,所以当小的数被分配某个数后不会造成数的重复,那么优先给小的数分配,所以就像其他题解所说:
“从大数开始向前,依次分配1”。
所以对于8我们先分配出了2,3又余3,我们先分配1给3,得到2,4这时候2可以被分配,那么我们就分配给2一个1,得到3和4,这时候还余1,我们就分配给4,得到3,5。
这里我来解释一下点赞数最多的题解的思路。
以下为引用部分:
本题要先用简单的数论和贪心找到最优解的组成方法,再用高精度乘法求积。
以2004为例,由于把2004分拆成若干个互不相等的自然数的和的分法只有有限种,因而一定存在一种分法,使得这些自然数的乘积最大。
若1作因数,则显然乘积不会最大。把2004分拆成若干个互不相等的自然数的和,因数个数越多,乘积越大。为了使因数个数尽可能地多,我们把2004分成2+3…+n直到和大于等于2004。
若和比2004大1,则因数个数至少减少1个,为了使乘积最大,应去掉最小的2,并将最后一个数(最大)加上1。
若和比2004大k(k≠1),则去掉等于k的那个数,便可使乘积最大。
-
例如15:s=2+3+4+5+6刚好大于15,s-15=5,所以把5去掉。
-
又例如13:s=2+3+4+5刚好大于13,s-13=1,所以去掉2,并把5加1,即3 4 6。
大家可能觉得这个和我们刚才所讲的不太一样,为什么要减呢?怎么想到的呢?显然这样减,比我们一个个循环加更快。
我来帮大家推导一下:
我们分出来了2,3,4......n这n-1个数然后余数是K(1<=K<=n)。
- 如果K==n,我们需要进行两轮分配,意思是从n分配到2还剩下1,需要再回去把1分配给最大的数(也就是n+1)最终得到3,4,5......n+2这也就应对了上文题解中的情况2;
- 如果K<n,我们进行一轮分配就好因为我们的余数是K,那么分配到n+1-K就停止了,拿15举例,先分配出了2,3,4,5余1,我们分配到5就停止了,(n+1-K=5)。 对于上篇题解他先分配出2,3,4......n,n+1。因为我们分出来n-1个数余数是K,而分配出n+1后会造成数不够,还差n+1-K,那么这也就对应前两行我们推导出的结果,去掉n+1-K,就相当于分配到了n+1-K,应为n+1-K经过分配后变成了,n+2-K,这不就相当于去掉了吗。所以这相当于找规律了。
这里我再帮大家解释一下一篇题解中的dp做法,对所有数取对数。
我们知道背包是尽可能使装的物品总价值更大,题解中定义了一个容量为n的背包,每个的价值为ln i;
以下为引用部分:
题目大意
将n(n≤10^4 )拆分成若干个互不相同数字之和(可以只有11个数),求这些数乘积的最大值。输出方案和最大值。
题解 楼上给了很多贪心的做法,然而并不是那么容易理解。这里给一个非常容易理解然而复杂度很劣的01背包做法吧。
互不相同这个条件可以改为从1,2,⋯,n这n个数中选出一些数,使得它们的和为n。但是,01背包只能处理从a个物品中选出总共b空间的物品,使得它们的价值和最大,可是我们要求乘积呀?
在数学里,对数有一个很好的性质:
lna+lnb=ln(a×b)
假如我们要选出一些数使得它们的乘积最大,就等价于这些数的对数之和最大。
因此题目就很显然了。n个物品,背包体积为n,每个物品体积Ci 为i,价值Wi 为lni......(详情参考源代码)。
有同学有疑惑,为什么背包问题不是求容量C所装的最大价值吗?你怎么保证他能把背包装满?
这里我解释一下,背包一定可以装满,因为最大乘积的序列和就为n。
不知道我有没有有讲清楚,因为背包求出来的是最大价值,如果我们剩下空间K没装,这不就相当于我们之前所说的余数K吗?所以大家认为要不要把K分配出去呢?明显是分配后的结果更大,这也就是n和n+1的分别拆开的数的最大乘积哪个更大,明显是n+1更大,所以空间不存在多余,一定会用完。