P1249 最大乘积

// Problem: P1249 最大乘积
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1249
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// User: Pannnn
#include <bits/stdc++.h>
using namespace std;
/*
把n分拆成若干个互不相等的自然数的和的分法只有有限种,因而一定存在一种分法,使得这些自然数的乘积最大。
因1作因数,则显然乘积不会最大。把n分拆成若干个互不相等的自然数的和,因数个数越多,乘积越大。
为了使因数个数尽可能多,把n分成2+3+...+k直到满足2+3+...+k <= n且2+3+...+k+(k+1)大于n,
令s = 2+3+...+k,一共k-1个数
若s < n,则还需要分配n - s。
如果能把数分到更小的数上,那么乘积更大,但不允许数重复,需要从大数开始向前,依次分配1
如 s = 2 + 3 + 4 + 5 + 6 + 7
例如 n - s等于1
分配后:2 + 3 + 4 + 5 + 6 + 8
例如n - s等于3
分配后:2 + 3 + 4 + 6 + 7 + 8
即从某个位置开始,全部加1
可视为从2 + 3 + ... + k + (k + 1)使得s > n后删去某个数
特殊情况,若和比n大1,则因数个数至少减少一个,为了使乘积最大,去掉最小的2,并将最后一个数加上1
否则,去掉等于s-n的那个数
此时乘法最大(去掉可以使其值变为1,不影响结果)
*/
vector<int> mul(vector<int> a, int b) {
vector<int> res;
int pre = 0;
for (int i = 0; i < a.size(); ++i) {
pre += a[i] * b;
res.push_back(pre % 10);
pre /= 10;
}
while (pre) {
res.push_back(pre % 10);
pre /= 10;
}
return res;
}
int main() {
vector<int> resQue;
int n;
cin >> n;
int sum = 0;
int tmp = 2;
while (sum <= n) {
sum += tmp;
resQue.push_back(tmp);
++tmp;
}
if (sum - n == 1) {
resQue.front() = 1;
++resQue.back();
} else {
resQue[sum - n - 2] = 1;
}
vector<int> mulRes(1, 1);
for (int i = 0; i < resQue.size(); ++i) {
if (resQue[i] == 1) { continue; }
cout << resQue[i] << " ";
mulRes = mul(mulRes, resQue[i]);
}
cout << endl;
for (int i = mulRes.size() - 1; i >= 0; --i) {
cout << mulRes[i];
}
cout << endl;
return 0;
}
posted @   Pannnn  阅读(154)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
-->
点击右上角即可分享
微信分享提示