【洛谷_P2569】股票交易

本博客探讨了如何利用单调队列解决一道关于股票交易的编程问题。题目要求在给定的交易规则和限制下,计算在TT天内能获得的最大利润。通过模拟交易并应用单调队列优化动态规划算法,可以找到最佳交易策略。

股票交易


题目描述

最近 lxhgww 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。

通过一段时间的观察,lxhgww 预测到了未来 TT 天内某只股票的走势,第 i 天的股票买入价为每股 AP_i
,第 i 天的股票卖出价为每股 BP_i (数据保证对于每个 i,都有 AP_i ≥ BP_iAP ),但是每天不能无限制地交易,于是股票交易所规定第 i 天的一次买入至多只能购买 AS_i 股,一次卖出至多只能卖出 BS_i股。

另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔 W 天,也就是说如果在第 i 天发生了交易,那么从第 i+1 天到第 i+W 天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,一个人的手里的股票数不能超过 MaxP

在第 11 天之前,lxhgww 手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然,TT 天以后,lxhgww 想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?

输入格式

输入数据第一行包括 3 个整数,分别是 T,MaxP,W。

接下来 TT 行,第 ii 行代表第 i-1 天的股票走势,每行 4 个整数,分别表示 AP_i, BP_i, AS_i, BS_i

输出格式

输出数据为一行,包括 11 个数字,表示 lxhgww 能赚到的最多的钱数。

输入输出样例

输入

5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1

输出

3

解题思路

模拟在每一天中,买股和卖股的情况,动态转移方程为:

f[i][j]=max(max(f[k][j])-j*a[i]);//{j<=as[i],i>w+1}

如果就这么简单的话,那我说这句话有什么意义?我们还要用单调队列维护这里面的最大值,那么程序就出来了:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int e,f[2010][2010],q[100010][3];
int a[
### 洛谷 P1284 三角形牧场 题目描述 奶牛们希望设计种新的牧场形状——由漂亮的白色栅栏围成的三角形牧场。建筑师 Hei 手中有 $n$ 块木板,每块木板的长度为整数值 $l_i$。她的目标是利用这些木板拼接个能够形成合法三角形的最大面积牧场。 #### 输入格式 输入的第行为个正整数 $n$ ($3 \leq n \leq 15$),代表拥有的木板数量;第二行为 $n$ 个正整数 $l_1, l_2, ..., l_n$ ($1 \leq l_i \leq 10^6$),分别表示各木板的长度。 #### 输格式 如果无法构成任何三角形,则输 `-1`;否则输能组成的最大面积,保留两位小数。 --- ### 解法分析 此问题的核心在于如何通过给定的木板组合找到满足三角形条件的最佳方案并计算其面积。以下是两种主要方法: #### 方法:动态规划 (DP) 定义状态 `dp[i][j]` 表示前 $i$ 条边中是否存在两条边分别为 $j$ $c-j-k$ 的情况,其中 $c=\sum_{k=1}^{n}{l_k}$ 是总周长的半[^2]。转移方程如下: ```cpp if ((j - l[i] >= 0 && dp[j - l[i]][k]) || (k - l[i] >= 0 && dp[j][k - l[i]])) dp[j][k] = true; ``` 最终判断是否能找到三个符合条件的边 $(a,b,c)$ 并验证它们是否可构成三角形: ```cpp inline bool check(int a, int b, int c) { if (a + b > c && a + c > b && b + c > a) return true; return false; } check(i, j, c - i - j); ``` 旦确认存在这样的三边组合,即可应用 **海伦公式** 计算面积: $$ S = \sqrt{p(p-a)(p-b)(p-c)} $$ 其中 $ p = \frac{a+b+c}{2} $ 是半周长。 --- #### 方法二:搜索算法 另种解法基于暴力搜索的思想,但由于直接穷举所有可能性会导致超时(TLE),因此需引入剪枝策略优化效率[^4]。具体实现步骤包括但不限于以下几个方面: - 对原始数组按升序排列; - 枚举当前尝试加入哪条边上; - 使用回溯技术逐步试探直至完成分配过程; - 结合均值不等式的理论依据进步缩小候选范围,即倾向于让三条边尽可能接近从而提升潜在最优解的概率。 下面是简化版伪代码展示这逻辑框架: ```python def dfs(index, sideA, sideB, sideC): global maxArea # 边界处理与更新最佳结果记录 currentPerimeter = sideA + sideB + sideC semiPerimeter = currentPerimeter / 2 areaCandidate = sqrt(semiPerimeter*(semiPerimeter-sideA)*(semiPerimeter-sideB)*(semiPerimeter-sideC)) if isValid(sideA, sideB, sideC): if areaCandidate > maxArea: maxArea = areaCandidate # 继续探索剩余选项 for nextIndex in range(index+1, lengthOfPlanks): newLength = lengths[nextIndex] # 分配至不同边缘之 dfs(nextIndex, sideA + newLength, sideB , sideC ) dfs(nextIndex, sideA , sideB + newLength, sideC ) dfs(nextIndex, sideA , sideB , sideC + newLength ) # 初始化调用入口函数 maxArea = -1 dfs(-1, 0, 0, 0) print("%.2f"%maxArea if maxArea != -1 else "-1") ``` 注意此处仅提供概念示意而非完整可用程序片段。 --- ### 海伦公式的实际运用实例 假设已知某组数据样本 $\{7, 9, 12\}$ 可成功构建有效三角形,则对应操作流程如下所示: 设 $s=(7+9+12)/2=14$ 代入得 $$ A=\sqrt{s(s−a)(s−b)(s−c)}=\sqrt{14(14−7)(14−9)(14−12)}≈26.83 $$ ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值