BUY LOW, BUY LOWER

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

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

//@version=5 indicator("Enhanced RSI [AI Optimized]", shorttitle="ERSI Pro", overlay=false, precision=2) // 参数设置 period = input.int(14, "基础周期") // int整型 emaPeriod = input.int(50, "EMA平滑周期") // int整型 overbought = input.int(65, "超买阈值基准") // int整型 oversold = input.int(35, "超卖阈值基准") // int整型 power = input.float(0.8, "非线性压缩指数") // float浮点型 useDynamicBands = input.bool(true, "启用动态阈值") // bool布尔型 // 计算真实波动范围(ATR) calcATR(src, len) => tr = math.max(high - low, math.max(math.abs(high - src[1]), math.abs(low - src[1]))) ta.ema(tr, len) // 核心计算逻辑 var float ersi = na var float upperBand = na var float lowerBand = na // ATR波动率因子 atr = calcATR(close, period) atrEMA = ta.ema(atr, emaPeriod) volatilityFactor = atr / atrEMA // 调整后的价格变化 delta = close - close[1] adjustedDelta = delta / math.sqrt(math.max(volatilityFactor, 0.1)) // 动态平滑系数 dynamicPeriod = period * (1 + volatilityFactor / 3) alpha = 2 / (dynamicPeriod + 1) // 计算方向强度 posDelta = math.max(adjustedDelta, 0) negDelta = math.max(-adjustedDelta, 0) avgGain = ta.ema(posDelta, int(alpha * 1000)) // PineScript特殊EMA实现 avgLoss = ta.ema(negDelta, int(alpha * 1000)) // 非线性压缩处理 rs = avgGain / math.max(avgLoss, 0.0001) // 防止除以零 compressedRS = math.pow(rs, power) ersi := 100 - 100 / (1 + compressedRS) // 动态阈值调整 volatilityAdj = 5 * (atr / ta.sma(atr, 50) - 1) upperBand := useDynamicBands ? (overbought + volatilityAdj) : overbought lowerBand := useDynamicBands ? (oversold - volatilityAdj) : oversold // 信号生成逻辑 longCondition = ta.crossover(ersi, lowerBand) shortCondition = ta.crossunder(ersi, upperBand) // 绘图 plot(ersi, "ERSI", color=#2962FF, linewidth=2) hline(50, "Midline", color=color.gray, linestyle=hline.style_dotted) band1 = plot(upperBand, "Upper Band", color=#FF6D00, linestyle=plot.style_circles) band2 = plot(lowerBand, "Lower Band", color=#00C853, linestyle=plot.style_circles) fill(band1, band2, color=color.new(#2962FF, 90), title="Dynamic Band") // 警报条件 plotshape(longCondition, title="Buy Signal", style=shape.triangleup, location=location.belowbar, color=#00C853, size=size.small) plotshape(shortCondition, title="Sell Signal", style=shape.triangledown, location=location.abovebar, color=#FF5252, size=size.small) // 策略回测模块 if (longCondition) strategy.entry("Long", strategy.long) else if (shortCondition) strategy.entry("Short", strategy.short) 问题有这些://@version=5: Pine Script™的版本5已过时。请使用当前版本,即6。(PINE_VERSION_OUTDATED) band1 = plot(upperBand, "Upper Band", color=#FF6D00, linestyle=plot.style_circles):The 'plot' function does not have an argument with the name 'linestyle' band2 = plot(lowerBand, "Lower Band", color=#00C853, linestyle=plot.style_circles):The 'plot' function does not have an argument with the name 'linestyle'
最新发布
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值