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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)