[haut] 1281: 邪能炸弹 dp

题目描述
正在入侵艾泽拉斯的古尔丹偶然间得到了一颗邪能炸弹,经过研究,他发现这是一颗威力极其巨大且难以控制的炸弹。但是精通邪能的古尔丹突然有了一个大胆的想法,他对炸弹进行了一些小小的改造。这使得炸弹需要n天的充能才能爆炸,在这n天中,每天炸弹的邪能值都会产生波动,波动值为xi,古尔丹唯一能控制的是使邪能值增加xi或减少xi,如果邪能值小于0或大于MAX,那么炸弹将会损坏并失效。机智如古尔丹当然会做出最优选择。而作为反抗军的情报人员,你知道炸弹的初始邪能值为begin,寿命为n天以及每天的波动值xi。你需要知道在第n天炸弹可能达到的最大邪能值。
输入
第一行为一个整数T,表示有T组测试实例。
对于测试实例:
第一行为三个整数 n,begin,MAX。1<=n<=50,0<=begin<=MAX,1<=MAX<=1000。
第二行一次为n个整数 x1,x2,x3,x4...xn。1<=xi<=1000
输出
对于每组测试实例输出一行,表示第n天炸弹可能达到的最大邪能值,如果炸弹无法避免邪能值低于0或者高于MAX则输出-1。
样例输入
2
3 5 10
5 3 7

3 3 8
5 2 10
样例输出
10
-1

思路:当时的写的是dfs ac了 可以构造一颗搜索树 然后搜索就好了
   题解是用的dp 设dp[i][j]为第i天时值为j的存在状态 1为存在 0为不存在 如果dp[i-1][j] = 1 那么可由此推出dp[i][j + Xi] 和 dp[i][j - Xi]的存在状态
   若j在i-1和i阶段取值0~Max内都不存在的话 直接可以返回-1了
dfs:
#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
int a[1010];
int n, b, Max;
int ans;

void dfs(int ret, int t)
{
    if (ret < 0 || ret > Max)
        return;
    if (t == n) {
        ans = max(ans, ret);
        return;
    }
    dfs(ret+a[t], t+1);
    dfs(ret-a[t], t+1);
}

int main()
{
    //freopen("1.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
        ans = -1;
        scanf("%d%d%d", &n, &b, &Max);
        for (int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        dfs(b, 0);
        printf("%d\n", ans);
    }
        
    return 0;
}
dp:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[55][1010];
int n, b, Max;
int x[55];


int main()
{
    //freopen("1.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d%d", &n, &b, &Max);
        for (int i = 1; i <= n; i++)
            scanf("%d", &x[i]);
        memset(dp, 0, sizeof(dp));
        dp[0][b] = 1;
        int flag;
        for (int i = 1; i <= n; i++) {
            flag = 0;
            for (int j = 0; j <= Max; j++) {
                if (dp[i-1][j]) {
                    if (j + x[i] <= Max) {
                        dp[i][j + x[i]] = 1;
                        flag = 1;
                    }
                    if (j - x[i] >= 0) {
                        dp[i][j - x[i]] = 1;
                        flag = 1;
                    }
                }
            }
            if (flag == 0) break;
        }
        int ans = -1;
        for (int i = Max; i >= 0; i--)
            if (dp[n][i]) {
                ans = i;
                break;
            }
        printf("%d\n", ans);
    }
    

    return 0;
}
 
 

 

 

转载于:https://www.cnblogs.com/whileskies/p/7287398.html

主要内容:本文详细介绍了一种QRBiLSTM(分位数回归双向长短期记忆网络)的时间序列区间预测方法。首先介绍了项目背景以及模型的优势,比如能够有效利用双向的信息,并对未来的趋势上限和下限做出估计。接着从数据生成出发讲述了具体的代码操作过程:数据预处理,搭建模型,进行训练,并最终可视化预测结果与计算分位数回归的边界线。提供的示例代码可以完全运行并且包含了数据生成环节,便于新手快速上手,深入学习。此外还指出了模型未来发展的方向,例如加入额外的输入特性和改善超参数配置等途径提高模型的表现。文中强调了时间序列的标准化和平稳检验,在样本划分阶段需要按时间序列顺序进行划分,并在训练阶段采取合适的手段预防过度拟合发生。 适合人群:对于希望学习和应用双向长短时记忆网络解决时序数据预测的初学者和具有一定基础的研究人员。尤其适用于有金融数据分析需求、需要做多一步或多步预测任务的从业者。 使用场景及目标:应用于金融市场波动预报、天气状况变化预测或是物流管理等多个领域内的决策支持。主要目的在于不仅能够提供精确的数值预计还能描绘出相应的区间概率图以增强结论置信程度。 补充说明:本教程通过一个由正弦信号加白噪构造而成的简单实例来指导大家理解和执行QRBiLSTM流程的所有关键步骤,这既方便于初学者跟踪学习,又有利于专业人士作为现有系统的补充参考工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值