P2466 [SDOI2008] Sue 的小球(区间dp)

news/2024/11/29 10:44:41/

P2466 [SDOI2008] Sue 的小球(区间dp)

链接:P2466 [SDOI2008] Sue 的小球
很有意思的一道题,想各种方法都无从下手,看了洛谷题解瞬间懂了。

题意

n n n 个物品,每个物品的位置在 x i x_i xi,价值为 y i y_i yi,且其价值每单位时间下降 v i v_i vi。当前你在位置 x 0 x_0 x0,每单位时间你可以移动一格距离,当你和物品重叠时可以瞬间获取该物品的价值。问获取所有物品后的最大价值 v a l val val 为多少,输出 v a l 1000 \frac {val}{1000} 1000val,保留三位小数作为答案。

思路

我们很容易想到移动的情况可能有很多种,可能一会向左一会向右,最终要拿到所有物品。我们可以想到用区间dp, f [ l ] [ r ] f[l][r] f[l][r] 为状态来进行转移,代表拿完该区间所有物品的最大价值。贪心的考虑我们拿完一个区间的物品后肯定要向外面扩展,要么停在在左端点要么停在右端点,不可能停在中间,于是我们又加一维状态 [ 0 / 1 ] [0/1] [0/1] 代表拿完当前区间物品后停在 l / r l/r l/r 端点。

重点:
此时我们会发现, f [ l ] [ r ] [ 0 / 1 ] f[l][r][0/1] f[l][r][0/1] 完全没有考虑时间对物品价值的影响,那么我们是否要再加一维代表时间呢?显然不行,这样时空复杂度都爆炸了,我们考虑如何维护时间的影响。
我们可以把每一步受到时间影响的代价算进去,因为要得到所有物品,那么当前我们没到的地方此后肯定都要经过,当前我们一步花费时间 t t t,那么没获取的物品的价值都会因此减少,并直接影响最终的答案。于是我们就有了结论:把当前每一步花费的时间对最终答案的影响直接计算进当前的答案。

具体如何维护时间的影响,可以考虑对每个物品减少的速度 v i v_i vi 维护一个前缀和,根据每一步的转移花费的时间 ∗ * 未获取的物品区间速度和, c o s t = t ∗ ∑ 1 n v i − ∑ l r v i cost = t * \sum_1^n {v_i} - \sum_l^r{v_i} cost=t1nvilrvi. 详情见代码。

代码

/*
f[i][j][2]:从起点出发已经得到 i~j段的彩蛋,且当前在i/j点的最大值
考虑到受时间影响,此状态不能表示时间,但我们可以把每一步受到时间影响的代价算进去,因为要得到所有彩蛋,那么当前我们没到的地方,每经过
时间t,彩蛋的价值都会减少,直接影响最终的答案,直接算进当前的答案中即可解决该问题
*/
#include <bits/stdc++.h>
using namespace std;#define ll long longconst int N = 1010;struct node{int x, y, v;bool operator <(const node& A)const{return x < A.x;}
}s[N];int n, x;
ll pre[N];
ll f[N][N][2]; // 从起点出发已经得到 i~j段的彩蛋,且当前在i/j点的最大值ll delet(int l, int r, ll t){ // 对整体的答案的影响return (pre[n] - pre[r] + pre[l - 1]) * t;
}int main(){// ios::sync_with_stdio(false);// cin.tie(0); cout.tie(0);scanf("%d%d", &n, &x);for(int i = 1; i <= n; i ++) scanf("%d", &s[i].x);for(int i = 1; i <= n; i ++) scanf("%d", &s[i].y);for(int i = 1; i <= n; i ++) scanf("%d", &s[i].v);sort(s + 1, s + 1 + n); // 按坐标排序memset(f, -0x3f, sizeof f);for(int i = 1; i <= n; i ++){ // 前缀和pre[i] = pre[i - 1] + s[i].v;}for(int i = 1; i <= n; i ++){f[i][i][0] = f[i][i][1] = 1LL * s[i].y - pre[n] * (abs(s[i].x - x));}// 区间dpfor(int i = 2; i <= n; i ++){for(int l = 1; l + i - 1 <= n; l ++){int r = l + i - 1;f[l][r][0] = max(f[l + 1][r][0] - delet(l + 1, r, s[l + 1].x - s[l].x), f[l + 1][r][1] - delet(l + 1, r, s[r].x - s[l].x)) + s[l].y;f[l][r][1] = max(f[l][r - 1][0] - delet(l, r - 1, s[r].x - s[l].x), f[l][r - 1][1] - delet(l, r - 1, s[r].x - s[r - 1].x)) + s[r].y;// for(int k = 0; k < 2; k ++){//     printf("f[%d][%d][%d] = %lld\n", l, r, k, f[l][r][k]);// }}}double ans = (double)max(f[1][n][0], f[1][n][1]) / 1000.0;printf("%.3lf", ans);return 0;
}

http://www.ppmy.cn/news/1129269.html

相关文章

【每日一题Day340】LC2251花期内花的数目 | 差分+哈希表+排序 排序+二分查找

花期内花的数目【LC2251】 给你一个下标从 0 开始的二维整数数组 flowers &#xff0c;其中 flowers[i] [starti, endi] 表示第 i 朵花的 花期 从 starti 到 endi &#xff08;都 包含&#xff09;。同时给你一个下标从 0 开始大小为 n 的整数数组 people &#xff0c;people[…

React useRequest解读

源码结构&#xff1a; 可以看到虽然是一个hooks&#xff08;具有一定功能且具备状态的单一函数&#xff09; 但是各种文件功能分得也是很细的&#xff0c;方便抽离和复用 useRequest.ts 抽离的原则还是单一功能原则 可以看出 真正的hooks实现是在Implement里 对于类型type的引…

C#并发编程的实现方式

一、多线程&#xff1a;是一种并发编程技术&#xff0c;它允许一个应用程序同时执行多个线程。每个线程都有自己的指令集和堆栈&#xff0c;可以在不同的CPU核心上并行运行&#xff0c;或者在一个CPU核心上通过时间片轮转的方式交替运行。多线程的主要优点是可以利用多核处理器…

Python数据和Json数据的相互转换

什么是JSON&#xff1f; JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据 JSON本质上是一个带有特定格式的字符串 主要功能:JSON就是一种在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言中的数据传递和交互 Python数据和Json数据的相互…

面试问到MySQL模块划分与架构体系怎么办

面试问到Mysql模块划分与架构体系怎么办 文章目录 1. 应用层连接管理器&#xff08;Connection Manager&#xff09;安全性和权限模块&#xff08;Security and Privilege Module&#xff09; 2. MySQL服务器层2.1. 服务支持和工具集2.2. SQL Interface2.3. 解析器举个解析器 …

MATLAB算法实战应用案例精讲-【优化算法】基于房地产市场的优化算法(REMARK)(附MATLAB代码实现)

代码实现 MATLAB main.m clc, clear rng(shuffle) format short e options.nDim = 2; options.nDemander = 80; options.nSupplier = ceil(options.nDemander/4); options.maxFrnd = ceil(options.nDemander/4); options.constrPer = 10; options.KsigmaD = 0.7; options.Ks…

docker-compose 网络配置- IP 主机名 hosts配置

docker-compose 配置IP、hostname、hosts配置 配置IP version: "3" networks:bd-network: # 声明网络external: true services:kafka: # 服务名称networks:bd-network: # 连接的网络名称ipv4_address: 172.2.0.102 # 配置IP配置 主机名 version: "3&quo…

嵌入式Linux应用开发-第七章-野火-正点原子IMX6ULL的LED驱动程序

嵌入式Linux应用开发-第七章-野火-正点原子IMX6ULL的LED驱动程序 野火IMX6ULL的LED驱动程序7.4 野火/正点原子 IMX6ULL的 LED驱动程序7.4.1 原理图7.4.1.1 野火 fire_imx6ull-pro开发板7.4.1.2 正点原子 Atk_imx6ull-alpha开发板 7.4.2 所涉及的寄存器操作7.4.2.1 野火 fire_im…