网站建设课程的感想在线考试系统网站开发
news/
2025/10/3 11:22:28/
文章来源:
网站建设课程的感想,在线考试系统网站开发,手机python编程软件,社交网站开发难度算法提高课整理
CSDN个人主页#xff1a;更好的阅读体验 原题链接
题目描述
给定一个长度为 n n n 的数组#xff0c;数组中的第 i i i 个数字表示一个给定股票在第 i i i 天的价格。
设计一个算法来计算你所能获取的最大利润#xff0c;你最多可以完成 k k k 笔交易…算法提高课整理
CSDN个人主页更好的阅读体验 原题链接
题目描述
给定一个长度为 n n n 的数组数组中的第 i i i 个数字表示一个给定股票在第 i i i 天的价格。
设计一个算法来计算你所能获取的最大利润你最多可以完成 k k k 笔交易。
注意你不能同时参与多笔交易你必须在再次购买前出售掉之前的股票。一次买入卖出合为一笔交易。
输入格式
第一行包含整数 n , k n,k n,k表示数组的长度以及你可以完成的最大交易笔数。
第二行包含 n n n 个不超过 1 0 4 10^4 104 的正整数表示完整的数组。
输出格式
输出一个整数表示最大利润。
数据范围 1 ≤ N ≤ 1 0 5 1 \le N \le 10^5 1≤N≤105, 1 ≤ k ≤ 100 1 \le k \le 100 1≤k≤100 思路
本题为 DP 问题可以使用 闫氏DP分析法 解题。
DP
状态表示 f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1 集合在前 i i i 天中进行买卖第 i i i 天【持有 ( 1 ) (1) (1) | 不持有 ( 0 ) (0) (0)】股票且已经完成 j j j 笔完整的交易先卖出后买入的所有方案的集合。属性 max \max max 状态计算 本题状态较复杂如何用 0 / 1 0/1 0/1 表示各种状态转移 0 → 0 0\rightarrow 0 0→0 继续不持有股票 0 → 1 0\rightarrow 1 0→1 买当天的股票 1 → 0 1\rightarrow 0 1→0 卖出手里的股票 1 → 1 1\rightarrow 1 1→1 继续持有股票。 解决了状态转移的问题考虑设计状态转移方程。观察下图状态机我们发现 f i , j , 0 f_{i,j,0} fi,j,0 由上一层的两个状态 f i − 1 , j , 0 , f i − 1 , j , 1 f_{i-1,j,0},f_{i-1,j,1} fi−1,j,0,fi−1,j,1 转移过来因此状态转移方程为f[j][0] max(f[j][0], f[j][1] w[i]); f i , j , 1 f_{i,j,1} fi,j,1 由上一层的两个状态 f i − 1 , j , 1 , f i − 1 , j − 1 , 0 f_{i-1,j,1},f_{i-1,j-1,0} fi−1,j,1,fi−1,j−1,0 转移过来因此状态转移方程为f[j][1] max(f[j][1], f[j - 1][0] - a[i]); 初始化 由于有的状态值为负数对应到实际情况就是亏钱的股票买卖所以我们即使求最大值也应该将所有状态都初始化为 − ∞ -\infty −∞。f[0][0][0] 0; 什么都没有当然是 0 0 0 咯~ 目标状态 f n , 0 ∼ k , 0 f_{n,0\sim k,0} fn,0∼k,0即所有日期都考虑了买卖次数不超过 k k k 次最后手里不剩股票的所有状态。 疑难解答
Q为什么状态的设计是先卖出再买入呢题中不是先买入嘛
A第一支股票第一次操作只有买或不买一定不可能是卖或不卖因此第一支股票买入时必须按照一次交易处理。 算法
时间复杂度 O ( n k ) O(nk) O(nk)空间复杂度 O ( n k ) O(nk) O(nk)。
发现空间卡的很紧容易 MLE。
注意到每次转移全部用的上一层的状态因此我们考虑滚动数组优化直接删掉 f f f 数组的第一维还是正确的。
AC Code C \text{C} C #include iostream
#include cstringusing namespace std;const int N 100010, M 110;int n, m;
int a[N];
int f[M][2]; // 滚动数组int main()
{scanf(%d%d, n, m);for (int i 1; i n; i )scanf(%d, a[i]);memset(f, -0x3f, sizeof f);f[0][0] 0; // 初始化for (int i 1; i n; i )for (int j 1; j m; j ){f[j][0] max(f[j][0], f[j][1] a[i]);f[j][1] max(f[j][1], f[j - 1][0] - a[i]);}int res 0;for (int i 0; i m; i )res max(res, f[i][0]);printf(%d\n, res);return 0;
}最后如果觉得对您有帮助的话点个赞再走吧
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925819.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!