2024.8.31杂记
P1249 最大乘积
题目描述
一个正整数一般可以分为几个互不相同的自然数的和,如
现在你的任务是将指定的正整数
输入格式
只一个正整数
输出格式
第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。
第二行是最大的乘积。
样例
输入样例 #1
10
输出样例 #1
2 3 5
30
解题思路
这里取自 离散小波变换° 的动态规划解法。
题目描述中“一个正整数一般可以分为几个互不相同的自然数的和”,也就是将自然数
那么将其视为
C++代码
#include <bits/stdc++.h>
#include <sstream>
using namespace std;
const int N = 10010;
typedef long long LL;
vector<int> mul(vector<int> A, int B) {
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || t; i++) {
if (i < A.size())
t += A[i] * B;
C.push_back(t % 10);
t /= 10;
}
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}
vector<int> intToVector(int x) { // x > 0
vector<int> X;
while (x) {
X.push_back(x % 10);
x /= 10;
}
return X;
}
int n;
double f[N], v[N]; // v 为价值
int w[N], path[N]; // path 存储路径
vector<int> ans; // 存储最终方案
int main() {
cin >> n;
for (int i = 1; i <= n; i++) { // 初始化
w[i] = i;
v[i] = log(i);
}
for (int i = 1; i <= n; i++)
for (int j = n; j >= i; j--) {
if (f[j - w[i]] + v[i] > f[j]) { // 滚动数组
f[j] = f[j - w[i]] + v[i];
path[j] = j - w[i];
}
}
for (int i = n; i; i = path[i])
ans.push_back(i - path[i]);
sort(ans.begin(), ans.end());
vector<int> res;
res.push_back(1);
for (int i = 0; i < ans.size(); i++) {
res = mul(res, ans[i]);
cout << ans[i] << ' ';
}
cout << endl;
for (int i = res.size() - 1; i >= 0; i--)
cout << res[i];
return 0;
}
本文来自博客园,作者:Cocoicobird,转载请注明原文链接:https://www.cnblogs.com/Cocoicobird/p/18390413
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架