BUY LOW, BUY LOWER

本文详细解析了求解最长下降子序列问题的算法实现,包括如何计算子序列长度及方案数,适用于初学者理解递推思想。

BUY LOW, BUY LOWER的代码+解释,主要参考POJ BUY LOW, BUY LOWER,比原文多了些注释和自己的理解

程序主要分为3部分:

  • 求以num[i] 结尾的最长下降子序列的长度dp
  • 求以num[i] 结尾的不重复的最长下降子序列的方案数 project
  • 选择最大的dp值,并求该dp值对应的方案数之和

注:该程序没有实现高精度的计算,所以不适用于数目较多的数据集

#include <stdio.h>
#define N 5005

int num[N];
int dp[N]; // 以num[i]结尾的最长下降子序列的长度
int project[N]; // 以num[i] 结尾的不重复的最长下降子序列的方案数目

int main()
{
    int n;
    while(scanf("%d", &n)){
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d", &num[i]);
            // 初始化dp, project
            dp[i] = 1;
            project[i] = 0;
        }
        // 计算dp,dp[i] = max(dp[j]) + 1
        for (int i = 2; i <= n; ++i)
        {
            int tempLen = 0;
            for (int j = 1; j < i; ++j)
            {
                if(num[j] > num[i] && tempLen < dp[j]){
                    tempLen = dp[j];
                }
            }
            // 就算没有一个能满足以上条件的,num[i]的dp[i]也是1
            dp[i] = tempLen + 1;
        }
        // 计算project, project[i] = sigma(project[j])
        // 这样初始化的意义?dp[i] == 1的情形是产生其他下降子序列的基础,所以要初始化为1
        for (int i = 1; i <= n; ++i)
            if(dp[i] == 1)
                project[i] = 1;
        for (int i = 2; i <= n; ++i)
        {
            for (int j = i - 1; j > 0; --j)
            {
                // 一般情况
                if(num[j] > num[i] && dp[j] + 1 == dp[i]){
                    project[i] += project[j];
                }
                // 特殊情况:遇到数字相同的情况
                if(num[j] == num[i]){
                    // 在dp[i] == 1的时候(也就是处在最长下降子序列的初始阶段(第一个数)),为了避免出现重复序列,
                    // 需要忽略一个数;
                    // 那为什么是dp[i]?事实上任意一个都可以,是哪个不都一样吗?并不影响序列后面的方案数
                    // 如果不是dp[i] == 1的情况(也就是虽然数字重复,但已经参与到了新的不重复的序列中),
                    // 由于要保存中间状态,就不能置为0,直接跳过就好
                    if(dp[i] == 1){
                        project[i] = 0;
                    }
                    break;
                }
            }
        }
        // 计算maxdp和maxLen
        int maxDp = 0;
        int maxLen = 0;
        for (int i = 1; i <= n; ++i)
        {
            if(maxDp < dp[i])
                maxDp = dp[i];
        }
        for (int i = 1; i <= n; ++i)
        {
            if(maxDp == dp[i])
                maxLen += project[i];
        }
        printf("%d %d\n", maxDp, maxLen);
    }
    return 0;
}

我说我看这道题看了一星期,你会信吗-_-

代码概述 该代码实现了一个**分时高抛低吸交易策略**,结合了**价格、成交量、RSI指标**等多因子信号,用于判断买卖点,并在图表中可视化交易信号与价格通道。 --- 代码解析 1. **基础价格计算** ```plaintext PRC_MA5 = MA(CLOSE, 5) PRC_MA10 = MA(CLOSE, 10) PRC_MA20 = MA(CLOSE, 20) ``` 计算收盘价的5日、10日和20日均线。 2. **价格通道计算** ```plaintext UPPER_BAND = PRC_MA20 + 2 * STD(CLOSE, 20) LOWER_BAND = PRC_MA20 - 2 * STD(CLOSE, 20) ``` 构建布林带(Bollinger Bands),中轨为20日均线,上下轨为±2倍标准差。 3. **相对强弱指标(RSI)** ```plaintext RSI6 = RSI(CLOSE, 6) RSI12 = RSI(CLOSE, 12) ``` 计算6日和12日RSI,用于判断超买(>70)和超卖(<30)状态。 4. **成交量分析** ```plaintext VOL_MA5 = MA(VOL, 5) VOL_RATIO = VOL / REF(VOL, 1) ``` 5日平均成交量与当日成交量和前一日的比率。 5. **买卖信号** ```plaintext BUY_SIGNAL = CROSS(CLOSE, LOWER_BAND) AND RSI6 < 30 AND VOL > VOL_MA5 SELL_SIGNAL = CROSS(UPPER_BAND, CLOSE) AND RSI6 > 70 ``` - 买入信号:价格上穿下轨,RSI6超卖,成交量高于5日均量 - 卖出信号:价格下穿上轨,RSI6超买 6. **分时高低点** ```plaintext MIN_LOW = LLV(LOW, 30) MAX_HIGH = HHV(HIGH, 30) ``` 获取过去30周期内的最低低价和最高高价。 7. **可视化部分** - 绘制图标和文字提示买卖信号和价格异动 - 绘制高低点标记 --- 知识点 1. **移动平均(MA)**:用于平滑价格波动,识别趋势方向。 2. **布林带(Bollinger Bands)**:由均线和标准差构成,衡量波动性并判断价格是否偏离正常范围。 3. **相对强弱指数(RSI)**:衡量价格变动的速度和幅度,识别超买或超卖状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值