当前位置: 首页 > news >正文

(区间 dp)洛谷 P1220 关路灯/P2466 Sue 的小球 题解

1.关路灯

题意

某一村庄在一条路线上安装了 n n n 盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少)。老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯。

为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯。开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边的路灯,而事实并非如此,因为在关的过程中适当地调头有可能会更省一些。

现在已知老张走的速度为 1 m / s 1m/s 1m/s,每个路灯的位置(是一个整数 a i a_i ai,即距路线起点的距离,单位: m m m)、功率( W W W),老张关灯所用的时间很短而可以忽略不计。

请你为老张编一程序来安排关灯的顺序,老张从下标为 c c c 的路灯开始走(即 c c c 可以马上被关掉),使从老张开始关灯时刻算起所有灯消耗电最少(灯关掉后便不再消耗电了)。

1 ≤ n ≤ 50 1\le n\le50 1n50 1 ≤ c ≤ n 1\le c\le n 1cn 1 ≤ W i ≤ 100 1\le W_i \le 100 1Wi100

思路

这是古早时候做的题了,当时没有写题解的意识。

其实这是一道经典的区间 dp 题。首先明确一点就是,老张遇到一个路灯就会关掉(难道眼睁睁看着继续功率损耗吗?反正关灯不消耗时间)。

可以看做关一段灯,是连续的。但是老张从哪个方向扫过去关灯呢?那么状态就要多一个维度,也就是“方向”:设 f i , j , o p f_{i,j,op} fi,j,op 表示,关掉编号在区间 [ i , j ] [i,j] [i,j] 的路灯,最终停在左( o p = 0 op=0 op=0)或右($op=1%)端点,消耗的最小功率。

s u m l , r = ∑ i = l r W i sum_{l,r}=\sum_{i=l}^{r}W_i suml,r=i=lrWi,那么:
s 1 = ( s u m 1 , i + s u m j + 1 , n ) f i , j , 0 = min ⁡ ( f i + 1 , j , 0 + ( a i + 1 − a i ) s 1 , f i + 1 , j , 1 + ( a j − a i ) s 1 ) \begin{matrix} s_1=(sum_{1,i}+sum_{j+1,n})\\ f_{i,j,0}=\min(f_{i+1,j,0}+(a_{i+1}-a_i)s_1,f_{i+1,j,1}+(a_j-a_i)s_1) \end{matrix} s1=(sum1,i+sumj+1,n)fi,j,0=min(fi+1,j,0+(ai+1ai)s1,fi+1,j,1+(ajai)s1)

分别表示从 i + 1 i+1 i+1 走到 i i i 和从 j j j 走到 i i i ,没有关闭的所有路灯损耗的功率(此时 i + 1 ∼ j i+1\sim j i+1j 的所有路灯全都被关闭)。
s 2 = ( s u m 1 , i − 1 + s u m j , n ) f i , j , 1 = min ⁡ ( f i , j − 1 , 0 + ( a j − a i ) s 2 , f i , j − 1 , 1 + ( a j − a j − 1 ) s 2 ) \begin{matrix} s_2=(sum_{1,i-1}+sum_{j,n})\\ f_{i,j,1}=\min(f_{i,j-1,0}+(a_j-a_i)s_2,f_{i,j-1,1}+(a_j-a_{j-1})s_2) \end{matrix} s2=(sum1,i1+sumj,n)fi,j,1=min(fi,j1,0+(ajai)s2,fi,j1,1+(ajaj1)s2)

答案即 min ⁡ ( f 1 , n , 0 , f 1 , n , 1 ) \min(f_{1,n,0},f_{1,n,1}) min(f1,n,0,f1,n,1)

代码参考下一题,敬请自行修改。

2.Sue 的小球

题意

Sue 的目标是要收集空中漂浮的彩蛋,Sue 将小船划到一个彩蛋的正下方,便可以在瞬间收集到这个彩蛋。然而,彩蛋有一个魅力值,这个魅力值会随着彩蛋在空中降落的时间而降低,Sue 要想得到更多的分数,必须尽量在魅力值高的时候收集这个彩蛋,且 Sue 希望收集到所有的彩蛋。

然而 Sandy 就没有 Sue 那么浪漫了,Sandy 希望得到尽可能多的分数,为了解决这个问题,他先将这个游戏抽象成了如下模型:

将大海近似的看做 x x x 轴,以 Sue 所在的初始位置作为坐标原点建立一个竖直的平面直角坐标系。

一开始空中有 n n n 个彩蛋,对于第 i i i 个彩蛋,他的初始位置用整数坐标 ( x i , y i ) (x_{i}, y_{i}) (xi,yi) 表示,游戏开始后,它匀速沿 y y y 轴负方向下落,速度为 v i v_{i} vi 单位距离/单位时间。Sue 的初始位置为 ( x 0 , 0 ) (x_{0}, 0) (x0,0),Sue 可以沿 x x x 轴的正方向或负方向移动,Sue 的移动速度是 1 1 1 单位距离/单位时间,使用秘密武器得到一个彩蛋是瞬间的,得分为当前彩蛋的 y y y 坐标的千分之一。

现在,Sue 和 Sandy 请你来帮忙,为了满足 Sue 和 Sandy 各自的目标,你决定在收集到所有彩蛋的基础上,得到的分数最高(输出分数保留三位小数)。

− 1 0 4 ≤ x i , y i , v i ≤ 1 0 4 -10^4 \leq x_{i},y_{i},v_{i} \leq 10^4 104xi,yi,vi104 n ≤ 1000 n \leq 1000 n1000

思路

其实这题和上一题相同了,只要把上一题的贡献变成损耗,然后令 s s s 等于初始所有彩蛋的魅力值,用 s s s 减去最小损耗(即 min ⁡ ( f 1 , n , 0 , f 1 , n , 1 ) \min(f_{1,n,0},f_{1,n,1}) min(f1,n,0,f1,n,1)),再除以 1000 1000 1000 即可。

不过这一题给的不是下标而是具体位置,而且还没排序,还需处理一下,具体细节见代码:

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
const ll N=1002,inf=0x3f3f3f3f;
ll n,x0,s;
ll sv[N];
struct node
{
	ll x,y,v;
}a[N];
bool cmp(node x,node y)
{
	return x.x<y.x;
}
ll f[N][N][2];//收集区间[i,j]在左/右,的损失值 
ll sum(ll a,ll b,ll c,ll d)
{
	return sv[b]-sv[a-1]+sv[d]-sv[c-1];
}
int main()
{
	scanf("%lld%lld",&n,&x0);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i].x);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i].y);
		s+=a[i].y;
	}
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i].v);
	a[++n].x=x0;
	sort(a+1,a+n+1,cmp);
	memset(f,inf,sizeof(f));
	for(int i=1;i<=n;i++)
	{
		if(a[i].x==x0)
		{
			f[i][i][0]=f[i][i][1]=0;
			break;
		}
	}
	for(int i=1;i<=n;i++)
	sv[i]=sv[i-1]+a[i].v;
	for(int len=2;len<=n;len++)
	{
		for(int i=1;i+len-1<=n;i++)
		{
			ll j=i+len-1;
			f[i][j][0]=min(f[i][j][0],min(f[i+1][j][0]+(a[i+1].x-a[i].x)*sum(1,i,j+1,n),
										f[i+1][j][1]+(a[j].x-a[i].x)*sum(1,i,j+1,n)));
			f[i][j][1]=min(f[i][j][1],min(f[i][j-1][0]+(a[j].x-a[i].x)*sum(1,i-1,j,n),
										f[i][j-1][1]+(a[j].x-a[j-1].x)*sum(1,i-1,j,n)));
		}
	}
	printf("%.3lf",(dd)(s-min(f[1][n][0],f[1][n][1]))/1000.0);
	return 0;
}

相关文章:

  • QCustomPlot安装及demo
  • 洛谷 三连击 暴力枚举
  • 如何在 CentOS 7 系统上以容器方式部署 GitLab,使用 ZeroNews 通过互联网访问 GitLab 私有仓库,进行代码版本发布与更新
  • 订单防重复提交与超时取消:AOP + 延迟队列实战
  • Tabnet介绍(Decision Manifolds)和PyTorch TabNet之TabNetRegressor
  • 鼎讯信通 通信安全的终极解决方案:机架式通信干扰机
  • 小白学习java第12天:IO流之缓冲流
  • 数据库守护神-WAL机制
  • 业务幂等性技术架构体系-接口幂等
  • 时序数据异常检测-综述
  • 【蓝桥杯】赛前练习
  • STM32 模块化开发指南 · 第 3 篇 环形缓冲区 RingBuffer 模块设计与单元测试
  • WHAT - React 安全地订阅外部状态源 - useSyncExternalStore
  • 我的Hexo自动Webhook部署方案
  • tree-sitter 的 grammar.js 编写方法
  • 如何进行预算考核
  • Ubuntu22环境下,Docker部署阿里FunASR的gpu版本
  • 【力扣hot100题】(085)单词拆分
  • P8647 [蓝桥杯 2017 省 AB] 分巧克力
  • 智能配电保护:公共建筑安全的新 “防火墙”
  • 企业网站建设上市公司/下载百度推广app
  • 企业网站设计网站/资源网
  • 网站建设南京/浙江网络科技有限公司
  • 建设信基金管理有限公司网站/app拉新项目
  • 做文字图片的网站/网络营销有哪些模式
  • 免费空间备案/seo实战密码在线阅读