P1220 关路灯

简介: P1220 关路灯

文章目录

  • P1220 关路灯
  • AC代码


P1220 关路灯

本题链接:P1220 关路灯

本博客给出本题截图

1.png

AC代码

代码解释:

这个题整体来看还是比较好想的,下面我们一步一步去分析这个问题:

首先我们去想这个题可以怎么去做,这里有三种思路

①dfs + 玄学剪枝

②贪心

③动态规划

这里我们来说第三种做法 (第一种第二种还没想过怎么代码实践

首先,不管我们怎么去写这个dp,都有一个我们绕不开的东西:我们需要不断的去计算消耗电量这个问题,这个其实就是时间(路程)×功率,这个是是根据时间的消耗是不断累加的,然后又因为dp的本质其实是最优选法的暴力,所以对于每一个不同的状态,如果我们都要去不断的叠加这个耗电量的话,很可能会TLE,那么对于处理这样的有反复计算叠加的问题,显然我们可以用 前缀和 的思维去进行优化.

好了,说完这一点,我们来看这个dp的具体实现部分 (敲黑板!

这么一个区间的问题,最简单的考虑方式就是由一个二维数组f[i][j]去表示,这个数组所表达的含义为[i, j]这一段的路灯已经全部熄灭的耗电量的最少值,即只有[1 ~ i)和(j, n]上的灯是处于点亮的状态时,当前的耗电量最小值

我们在定义到现在,需不需要再补充点什么东西呢?显然是需要的,我们虽然按照如上的方式去定义了f[i][j],但是,我们却不知道我们所处在哪个位置,即我们虽然保证了[i, j]上的所有灯都是处于熄灭的状态,但是我们却不知道我们现在在哪个位置,因为位置是决定时间的,而时间是决定耗电量的关键,故我们还需要规定一下我们的位置,显然,我们只可能处在i这个点上或者j这个点上,故我们不妨去规定f[i][j][0]代表[i, j]之间所有的灯都处于熄灭的状态且我们站在i这个点,f[i][j][1]代表[i, j]之间所有的灯都处于熄灭的状态且我们站在j这个点

以上,就是我们的dp方程的定义,下面,也是最难的,如何去写这个状态转移方程:

有初始化:

memset(f, 0x3f, sizeof f);
f[c][c][0] = f[c][c][1] = 0;

显然对于每一个f[i][j],我们都要去分两个方面去思考状态转移方程:即分别去计算f[i][j][0]和f[i][j][1]的min,下面去介绍如何计算:

对于f[i][j][0]这个点,我们只可能从f[i + 1][j]转移而来,即f[i][j][0] = min(f[i + 1][j][0] + num1, f[i + 1][j][1] + num2);,其中num1和num2分别指从f[i + 1][j][0]和f[i + 1][j][1] 转移到f[i][j][0]的过程中,其余灯泡的耗电量

在本题解的最开头已经说明利用 前缀和 的思维去进行优化,这里来说具体时间,我们的p数组就是前缀和数组,d数组代表的是我们的距离数组,那么我们在从i + 1移动到i的这个过程中消耗的时间(即路程)分别为:d[i + 1] - d[i],d[j] - d[i],那么在这两个过程中哪些灯泡是正在处于点亮耗电状态呢:p[i] + p[n] - p[j],(对这一步有疑问的话可以去模拟一下例子),f[i][j][1]的转移方法和f[i][j][0]一致,这里不再过多赘述,读者可以自己写一下,和我的代码进行对比即可

那么剩下的就是迈向成功的最后一步:如何去写for循环

因为在c处的灯是瞬间熄灭的,所以熄灭灯的长度最少是从2开始的,且不能超过n,然后开始枚举左端点即可,利用l(长度)和i(左端点)可以计算出右端点,即:

for (int l = 2; l <= n; l ++ )
    for (int i = 1; i + l - 1 <= n; i ++ )
      int j = i + l - 1;

最后,因为我们不知道是在1处有最小值还是在n处有最小值,故直接对f[1][n][0]f[1][n][1]取最小值即可

代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 55;
int n, c;
int f[N][N][2];
int p[N], d[N];
int main()
{
  int n, c;
  cin >> n >> c;
  for (int i = 1; i <= n; i ++ )
  {
    int w;
    cin >> d[i] >> w;
    p[i] = p[i - 1] + w;
  }
  memset(f, 0x3f, sizeof f);
  f[c][c][0] = f[c][c][1] = 0;
  for (int l = 2; l <= n; l ++ )
    for (int i = 1; i + l - 1 <= n; i ++ )
    {
      int j = i + l - 1;
      f[i][j][0] = min(f[i + 1][j][0] + (d[i + 1] - d[i]) * (p[i] + p[n] - p[j]), f[i + 1][j][1] + (d[j] - d[i]) * (p[i] + p[n] - p[j]));
      f[i][j][1] = min(f[i][j - 1][0] + (d[j] - d[i]) * (p[i - 1] + p[n] - p[j - 1]), f[i][j - 1][1] + (d[j] - d[j - 1]) * (p[i - 1] + p[n] - p[j - 1]));
    }
  cout << min(f[1][n][0], f[1][n][1]) << endl;
  return 0;
}




目录
相关文章
|
10月前
|
边缘计算 安全 数据安全/隐私保护
智能接入网关
智能接入网关SAG(Smart Access Gateway)是阿里云提供的软件定义广域网SD-WAN(Software Defined Wide Area Network)解决方案。企业可通过智能接入网关实现一站式接入阿里云,获得更加智能、安全和可靠的上云体验。
136 4
|
6天前
|
存储 监控 安全
工业物联网关应用:PLC数据通过智能网关上传阿里云实战
本文介绍如何使用智能网关将工厂PLC数据传输至阿里云平台,适合中小企业远程监控设备状态。硬件准备包括三菱FX3U PLC、4G智能网关和24V电源。接线步骤涵盖PLC编程口与网关连接、运行状态检测及天线电源接入。配置过程涉及通讯参数、阿里云对接和数据点映射。PLC程序关键点包括数据上传触发和温度值处理。阿里云平台操作包含实时数据查看、数据可视化和规则引擎设置。最后提供常见故障排查表和安全建议,确保系统稳定运行。
40 1
|
10月前
|
传感器 数据采集 监控
什么是物联网通信网关?
物联网通信网关是连接物联网设备与云或外部网络的关键桥梁。
201 2
|
10月前
|
网络架构
光纤接入网
大家还记得我们通过运营商提供的网线甚至是电话线上网的经历吧,那时上网使用xDSL(数字用户线路,Digital Subscriber Line)网络技术,xDSL技术是数字用户线路的所有类型的总称,包括RADSL、SDSL、HDSL、ADSL、VDSL和IDSL,乃至后续的G.fast技术。这些技术的传输是越来越快,但带宽小、传输距离短,是xDSL无法跨越的界限。 铜退光进,采用光纤技术实现数据的网络接入和传输,已经成为运营商的首选解决方案。下面介绍三种网络接入方式: 1.点到点网络P2P
|
人工智能 编解码 安全
凯迪仕、德施曼、华为斗法,智能门锁勇闯安全关
大数据、物联网、人工智能、云计算等新一代信息技术的快速发展,广泛应用于各类家电家具,门锁的智能水平与日俱增。
148 0
|
机器学习/深度学习 人工智能 智能设计
智能无线接入网的崛起
智能无线接入网的崛起
220 0
智能无线接入网的崛起
|
数据采集 弹性计算 网络协议
智能接入网关介绍|学习笔记
快速学习智能接入网关介绍
智能接入网关介绍|学习笔记
|
网络安全 数据安全/隐私保护 网络虚拟化
智能接入网关接入|学习笔记
快速学习智能接入网关接入
智能接入网关接入|学习笔记
|
网络安全 数据安全/隐私保护 数据中心
SAG-1000配置和智能接入网关的高级使用|学习笔记
快速学习SAG-1000配置和智能接入网关的高级使用
SAG-1000配置和智能接入网关的高级使用|学习笔记
开关电源模块 遥控开/关电路
模块电源的遥控开关操作,是通过 REM 端进行的。一般控制方式有两种: (1)REM 与-VIN(参考地)相连,遥控关断,要求 VREF<0.4V。REM 悬空或与+VIN 相连,模块工作,要求 VREM>1V。 (2)REM 与 VIN 相连,遥控关断,要求 VREM<0.4V。REM 与+VIN 相连,模块工作,要求 VREM>1V。REM 悬空,遥控关断,即所谓“悬空关断”(-R)。
开关电源模块 遥控开/关电路