洛谷题目:P1018 [NOIP 2000 提高组] 乘积最大 题解

embedded/2025/3/22 12:02:42/

题目传送门:

P1018 [NOIP 2000 提高组] 乘积最大 - 洛谷 (luogu.com.cn)

前言:

本题可以使用DP来解决。动态规划的核心思想是将一个复杂的问题分解为多个简单的子问题,并通过求解子问题的最优解来得到原问题的最优解。在本题中,我们通过逐步增加乘号的数量和数字串的长度,利用之前计算出的子问题的最优解来计算当前问题的最优解。已下是题目具体实现步骤:

#步骤:

        1、状态定义:

                设 dp[i][j]  表示在前  i  个数字当中插入  j  个乘号所能得到的最大乘积。这里的  i  的范围是从到 1 到  N  , j  的范围是从 0 到 k 。

        2、边界条件:

                当没有乘号时, dp[i][0] 就是前  i  个数字组成的整数。例如,对于数字串 123, dp[2][0]   就是数字 12。

        3、状态转移方程:

                对于 dp[i][j]  ,我们需要枚举最后一个乘号插入的位置  k(j<k<i)  。插入最后一个乘号后,数字串被分成两个部分:前  k  个数字中插入了  j-1  个乘号,以及第  K+1  个数字到第  i  个数字组成的整数。

        因此,状态转移方程公式为:


dp[i][j]=max_{j<k<i} dp([k][j-1]\times num(k+1,i)) 

其中,num(k+1,i)  表示从第  k+1  数字到第  i  个数字组成的整数。

        4、高精度计算:

                由于最终结果可能非常大,超出了普通整数类型(如 intlong long)的表示范围,所以需要使用高精度计算。在代码中,我们使用 vector<int> 来存储高精度数,每个元素代表一位数字,并且低位在前,高位在后。同时,实现了高精度乘法函数 multiply 来进行乘法运算,以及比较函数 isGreater 来比较两个高精度数的大小。

        5、最终结果:

                最终答案存储在  dp[N][K]  中,即在前  N  个数字中插入  K  个乘号所能获得的最大乘积。

##复杂度分析:

        1、时间复杂度:

                由于有三层嵌套循环,每层循环的时间复杂度分别为  K  和  N  和  N  相关,并且高精度乘法的时间复杂度与数字程度的平方成正比,所以总的时间复杂度为  O(K\times N^{2} \times M^{2} )  ,其中  M  是高精度数的最大长度。

        2、空间复杂度:

                主要用于 dp  数组,其大小为   N \times K \times M   ,所以总的空间复杂度为   O(N\times K\times M)  。

###代码:

#include <bits/stdc++.h>
using namespace std;
vector<int> m(const vector<int>& a, const vector<int>& b) {vector<int> res(a.size() + b.size());for (int i = 0; i < a.size(); ++i) {for (int j = 0; j < b.size(); ++j) {res[i + j] += a[i] * b[j];res[i + j + 1] += res[i + j] / 10;res[i + j] %= 10;}}while (res.size() > 1 && res.back() == 0) res.pop_back();return res;
}
bool G(const vector<int>& a, const vector<int>& b) {if (a.size() != b.size()) return a.size() > b.size();for (int i = a.size() - 1; i >= 0; --i) {if (a[i] != b[i]) return a[i] > b[i];}return false;
}
vector<int> S(const string& s) {vector<int> num;for (int i = s.size() - 1; i >= 0; --i) {num.push_back(s[i] - '0');}return num;
}
void P(const vector<int>& num) {for (int i = num.size() - 1; i >= 0; --i) {cout << num[i];}cout << endl;
}
int main() {int n, k;cin >> n >> k;string ns;cin >> ns;vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(k + 1));for (int i = 1; i <= n; ++i) {dp[i][0] = S(ns.substr(0, i));}for (int j = 1; j <= k; ++j) { for (int i = j + 1; i <= n; ++i) {  for (int l = j; l < i; ++l) {  vector<int> product = m(dp[l][j - 1], S(ns.substr(l, i - l)));if (G(product, dp[i][j])) {dp[i][j] = product;}}}}P(dp[n][k]);return 0;
}


http://www.ppmy.cn/embedded/174684.html

相关文章

高频SQL50题 第一天 | 1757. 可回收且低脂的产品、584. 寻找用户推荐人、595. 大的国家、1683. 无效的推文、1148. 文章浏览 I

1757. 可回收且低脂的产品 题目链接&#xff1a;https://leetcode.cn/problems/recyclable-and-low-fat-products/description/?envTypestudy-plan-v2&envIdsql-free-50 状态&#xff1a;已完成 考点&#xff1a;无 select product_id from Products where low_fats Y a…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加导出数据功能

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加导出数据功能📚页面效果📚指令输入�…

Windows 事件日志中登录类型(Logon Type)

Windows 登录类型&#xff08;Logon Type&#xff09;用于标识用户通过何种方式登录到系统&#xff0c;在安全审计日志&#xff08;如Windows事件日志&#xff09;中记录不同的登录行为。以下是常见的登录类型及其含义&#xff1a; 常见登录类型 交互式登录&#xff08;Interac…

Pytest的数据驱动DDT

1、ddt的语法&#xff1a; pytest.mark.parametrize(“case”, case_all) 是个装饰器&#xff0c;里面两个数据&#xff1a; case 和cases_all意思就是&#xff1a; 将cases_all里每个成员依次传递给case这个变 量&#xff1b; cace注意要加引号&#xff0c;虽然是个变量 但是要…

Java学习笔记-XXH3哈希算法

XXH3是由Yann Collet设计的非加密哈希算法&#xff0c;属于XXHash系列的最新变种&#xff0c;专注于极速性能与低碰撞率&#xff0c;适用于对计算效率要求极高的场景。 极速性能 在RAM速度限制下运行&#xff0c;小数据&#xff08;如 1-128 字节&#xff09;处理可达纳秒级&…

验证码设计与前端安全:实现方式、挑战与未来发展趋势深度分析

验证码&#xff08;CAPTCHA&#xff09;是一种用于区分人类用户和自动化程序&#xff08;如机器人&#xff09;的技术&#xff0c;广泛应用于登录、注册、表单提交等场景。然而&#xff0c;验证码的设计和实现不仅关乎用户体验&#xff0c;还涉及到前端安全问题。 1. 验证码的…

机器学习之KL散度推导

机器学习之KL散度推导 预备知识 熵、交叉熵、条件熵 熵 (Entropy) 这一词最初来源于热力学。1948年&#xff0c;克劳德爱尔伍德香农将热力学中的熵引入信息论&#xff0c;所以也被称为香农熵 (Shannon entropy)、信息熵 (information entropy)。 对于具体熵的定义和用法推荐…

Python第六章07:元组的定义和操作

# tuple元组的定义和操作# tuple元组定义用小括号&#xff1a;(1,2,3,4,5),可以是不同类型元素 # 给变量定义元组时&#xff0c;写括号不写tuple&#xff1a; a (1,2,3,4,5) # 变量 &#xff08;&#xff09; 变量 tuple&#xff08;&#xff09; 空元组变量 # tuple…