2023牛客暑期多校第五场 H.Nazrin the Greeeeeedy Mouse

本文介绍了如何解决一个涉及动态规划的01背包问题,通过移除容量条件并利用特殊数据结构(背包大小递增),将复杂度从O(N^3*m)优化到O(N^2*m),最后给出C++代码实现。

题目大意

一个小老鼠有 m m m 次偷东西机会,每次背包大小为 s z i sz_i szi ,有 n n n 件物品,大小 a i a_i ai ,价值 b i b_i bi ,每次只能顺序拿去(或不拿),求最大的价值和。
保证 s z i > s z i − 1 sz_i>sz_{i-1} szi>szi1
1 ≤ n , a i , s z i ≤ 200 1\leq n,a_i,sz_i \leq 200 1n,ai,szi200
1 ≤ m , b i ≤ 1 0 5 1\leq m,b_i \leq 10^5 1m,bi105

题解

一道明显的DP题,如果只看一次机会就是裸的01背包。
考虑枚举机会转移的时机,将容量,当前位置写进转移式子,
这是一个裸暴力(悲)。
转移的复杂度大致可以估算为 O ( N 3 ∗ m ) O(N^3*m) ON3m
时间明显超标。

去除容量

我们转念一想,容量对于最大值的计算实际上帮助不大,
由于数据在 200 200 200
我们可以提前打出某容量在一段区间里的最大价值。
容易想到 f l , r , s z = m a x ( f l , r − 1 , s z − a r + b r , f l , r − 1 , s z ) f_{l,r,sz}=max(f_{l,r-1,sz-a_r}+b_r,f_{l,r-1,sz}) fl,r,sz=max(fl,r1,szar+br,fl,r1,sz)
容量的计算就可以舍去了。

我们重新定义DP式子,将机会和当前位置写入转移式。
容易得到
d p x , i = m a x ( d p x − 1 , y + f y + 1 , i , s z i ) ( 0 ≤ y ≤ i ) dp_{x,i}=max(dp_{x-1,y}+f_{y+1,i,sz_i})(0\leq y\le i) dpx,i=max(dpx1,y+fy+1,i,szi)(0yi)
复杂度为 O ( N 2 ∗ m ) O(N^2 *m) O(N2m)

特殊条件

我们发现 s z sz sz的值是递增的,单独考虑,一个大的背包造成的贡献一定优于或等于一个小的背包。
所以我们只需要选取最后 n n n 组背包求解即可。
复杂度优化为 O ( N 3 ) O(N^3) O(N3)

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N=205;
int dp[N][N];
int f[N][N][N];
int a[N],b[N];
int sz[N];
int n,m,tot,ans;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i],&b[i]);
    for(int i=1;i<=m;i++)
    {
        int a;
        scanf("%d",&a);
        if(i+n>=m)
            sz[++tot]=a;               //递增的特殊性
    }
    for(int l=1;l<=n;l++)
        for(int r=l;r<=n;r++)
        {
        	for(int siz=a[r];siz<=200;siz++)               //预处理容量
                f[l][r][siz]=max(f[l][r-1][siz-a[r]]+b[r],f[l][r-1][siz]);
			for(int k=0;k<=200;k++)
				f[l][r][k]=max(f[l][r][k],f[l][r-1][k]);
		}
            
	for(int i=1;i<=tot;i++)
        for(int j=1;j<=n;j++)
            for(int y=0;y<=j;y++)
            {
            	dp[i][j]=max(dp[i-1][y]+f[y+1][j][sz[i]],dp[i][j]);
            	ans=max(dp[i][j],ans);
			}
	printf("%d",ans);
}

总结

注意看题目给出的特殊的数据。

该数据集通过合成方式模拟了种发动机在运行过程中的传感器监测数据,旨在构建一个用于机械系统故障检测的基准资源,特别适用于汽车领域的诊断分析。数据按固定时间间隔采集,涵盖了发动机性能指标、异常状态以及工作模式等维度信息。 时间戳:数据类型为日期时间,记录了每个数据点的采集时刻。序列起始于2024年12月24日10:00,并以5分钟为间隔持续生成,体现了对发动机运行状态的连续监测。 温度(摄氏度):以浮点数形式记录发动机的温度读数。其数值范围通常处于60至120摄氏度之间,反映了发动机在常规工况下的典型温度区间。 转速(转/分钟):以浮点数表示发动机曲轴的旋转速度。该参数在1000至4000转/分钟的范围内随机生成,符合数发动机在正常运转时的转速特征。 燃油效率(公里/升):浮点型变量,用于衡量发动机的燃料利用效能,即每升燃料所能支持的行驶里程。其取值范围设定在15至30公里/升之间。 振动_X、振动_Y、振动_Z:这三个浮点数列分别记录了发动机在三维空间坐标系中各轴向的振动强度。测量值标准化至0到1的标度,较高的数值通常暗示存在异常振动,可能与潜在的机械故障相关。 扭矩(·米):以浮点数表征发动机输出的旋转力矩,数值区间为50至200·米,体现了发动机的负载能力。 功率输出(千瓦):浮点型变量,描述发动机单位时间内做功的速率,取值范围为20至100千瓦。 故障状态:整型分类变量,用于标识发动机的异常程度,共分为四个等级:0代表正常状态,1表示轻微故障,2对应中等故障,3指示严重故障。该列作为分类任务的目标变量,支持基于传感器数据预测故障等级。 运行模式:字符串类型变量,描述发动机当前的工作状态,主要包括:怠速(发动机运转但无负载)、巡航(发动机在常规负载下平稳运行)、重载(发动机承受高负荷或高压工况)。 数据集整体包含1000条记录,每条记录对应特定时刻的发动机性能快照。其中故障状态涵盖从正常到严重故障的四级分类,有助于训练模型实现故障预测与诊断。所有数据均为合成生成,旨在模拟真实的发动机性能变化与典型故障场景,所包含的温度、转速、燃油效率、振动、扭矩及功率输出等关键传感指标,均为影响发动机故障判定的重要因素。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值