POJ1032 Parliament
题目来源:http://poj.org/problem?id=1032
题目大意:给定一个正整数N(5<=N<=1000),将N拆为若干个不同的数使得它们的乘积最大(找到一组互不相等,和为N,乘积最大的正整数)。
输入:N
输出:选择的数,升序输出。
Sample Input
7
Sample Output
3 4
假设不考虑拆成不等的数这个条件,那么依我们的经验应该是拆成相等的数乘积最大。加上这个条件之后,就应该是相邻的数乘积最大。那么给定一个N时,我们希望能将它拆为尽可能小的连续的数。而选择的数一定不能小至1,因为乘1不改变目标值,起不到作用纯属浪费。所以最好拆到2.当从2开始的序列累加和到某个数即将超过N时,停下,将剩下的数由高位向低位每个数的值增加1.剩余的数最多会把所有的数都加了1,还剩1个,(如果剩的比这还多,在开始从2往上累加时是不会停下来的,由数列求和公式可知。)若还剩1则再加到最的数上去。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1032 Parliament 3 // Memory: 280K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 9 using namespace std; 10 11 int main() { 12 int N; 13 cin >> N; 14 int cnt; 15 int sum = 0; 16 for (cnt = 0; sum + 2 + cnt<= N; ++cnt) { 17 sum += (2 + cnt); 18 } 19 int left = N - sum; 20 int p = 1 + cnt; 21 while (left > 0) { 22 --p; 23 --left; 24 } 25 if (p == 0) { 26 for (int i =3; i < 2 + cnt; ++i) { 27 cout << i << " "; 28 } 29 cout << 3 + cnt << endl; 30 } else if (p == 1) { 31 for (int i =3; i < 2 + cnt; ++i) { 32 cout << i << " "; 33 } 34 cout << 2 + cnt << endl; 35 } else if (p == cnt + 1) { 36 for (int i =2; i < 1 + cnt; ++i) { 37 cout << i << " "; 38 } 39 cout << 1 + cnt << endl; 40 } else { 41 for (int i =2; i <= p; ++i) { 42 cout << i << " "; 43 } 44 for (int i = p + 2; i < cnt + 2; ++i) { 45 cout << i << " "; 46 } 47 cout << 2 + cnt << endl; 48 } 49 system("pause"); 50 return 0; 51 }