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则再加到最的数上去。

 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 }
View Code
原文地址:https://www.cnblogs.com/dengeven/p/3229143.html