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

P1220 关路灯

P1220 关路灯

▍题意
一条笔直的道路上装有 n n n 盏路灯,每盏路灯的位置为 x i x_i xi,功率为 w i w_i wi。初始时,人物位于第 c c c 盏路灯处,且该路灯处于开启状态,其余路灯均关闭。每次可以向左或向右移动一单位距离,耗时 1 1 1 秒;到达路灯处可立即关闭该灯(不耗时)。移动过程中,所有未关闭的路灯每秒消耗等于其功率的电力。求关闭所有路灯时,最小总电力消耗(仅计算移动过程中消耗的电力)。
数据范围: 1 ≤ n ≤ 50 1 \leq n \leq 50 1n50 1 ≤ c ≤ n 1 \leq c \leq n 1cn 0 ≤ x i ≤ 1000 0 \leq x_i \leq 1000 0xi1000(位置单调递增), 1 ≤ w i ≤ 100 1 \leq w_i \leq 100 1wi100

▍分析
动态规划求解。定义 d p [ l ] [ r ] [ 0 / 1 ] dp[l][r][0/1] dp[l][r][0/1] 表示已经关闭区间 [ l , r ] [l, r] [l,r] 内所有路灯后,停留在左端点 0 0 0)或右端点 1 1 1)时的最小电力消耗。

  • 状态转移:从小区间向大区间扩展:
    • d p [ l ] [ r ] [ 0 ] dp[l][r][0] dp[l][r][0] 有两种来源:
      • d p [ l + 1 ] [ r ] [ 0 ] dp[l+1][r][0] dp[l+1][r][0] 左移到 l l l:消耗时间 ( x l + 1 − x l ) × 剩余功率和 (x_{l+1} - x_l) \times \text{剩余功率和} (xl+1xl)×剩余功率和
      • d p [ l + 1 ] [ r ] [ 1 ] dp[l+1][r][1] dp[l+1][r][1] 左移到 l l l:消耗时间 ( x r − x l ) × 剩余功率和 (x_r - x_l) \times \text{剩余功率和} (xrxl)×剩余功率和
    • d p [ l ] [ r ] [ 1 ] dp[l][r][1] dp[l][r][1] 有两种来源:
      • d p [ l ] [ r − 1 ] [ 0 ] dp[l][r-1][0] dp[l][r1][0] 右移到 r r r:消耗时间 ( x r − x l ) × 剩余功率和 (x_r - x_l) \times \text{剩余功率和} (xrxl)×剩余功率和
      • d p [ l ] [ r − 1 ] [ 1 ] dp[l][r-1][1] dp[l][r1][1] 右移到 r r r:消耗时间 ( x r − x r − 1 ) × 剩余功率和 (x_r - x_{r-1}) \times \text{剩余功率和} (xrxr1)×剩余功率和
  • 关键优化
    • 预处理功率前缀和 s u m [ i ] = ∑ k = 1 i w k sum[i] = \sum_{k=1}^{i} w_k sum[i]=k=1iwk

    • 转移时,剩余功率和为分两种情况:

      • c o s t 1 = s u m [ n ] − ( s u m [ r ] − s u m [ l ] ) cost1=sum[n]-(sum[r]-sum[l]) cost1=sum[n](sum[r]sum[l])
      • c o s t 2 = s u m [ n ] − ( s u m [ r − 1 ] − s u m [ l − 1 ] ) cost2=sum[n]-(sum[r-1]-sum[l-1]) cost2=sum[n](sum[r1]sum[l1])

      分别表示关闭区间 [ l + 1 , r ] 、 [ l , r − 1 ] [l+1,r]、[l,r-1] [l+1,r][l,r1] 的消耗电力总和。

  • 初始化 d p [ c ] [ c ] [ 0 ] = d p [ c ] [ c ] [ 1 ] = 0 dp[c][c][0] = dp[c][c][1] = 0 dp[c][c][0]=dp[c][c][1]=0(起点无耗时)。
    时间复杂度: O ( n 2 ) O(n^2) O(n2)(区间DP枚举 l , r l, r l,r)。

▍参考代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
/*
动态规划状态表示:f[l][r][0/1]集合:len=r-l+1,(所有的)关闭区间长度为 len ,且停留在 l/r(0/1) 点的消耗电力方案。属性:Min 最小值状态计算:子集划分:- cost1=sum[n]-(sum[r]-sum[l]),cost2=sum[n]-(sum[r-1]-sum[l-1]),分别表示关闭区间[l+1,r]、[l,r-1]的消耗电力总和。- 分 2 大类,4 种情况进行转移类型 1:停留在 l 左端点的方案,取最小值Min( 1),2) )。1) f[l][r][0], [l,r]<-[(l+1),r], time=x[l+1]-x[l],总消耗功率:time*cost, f[l][r][0]=f[l+1][r][0] + time*cost;2) f[l][r][0], [l,r]<-[l+1,(r)], time=x[r]-x[l],总消耗功率:time*cost, f[l][r][0]=f[l+1][r][1] + time*cost;类型 2:停留在 r 右端点的方案,取最小值Min( 3),4) )。3) f[l][r][1], [(l),r-1]->[l,r], time=x[r]-x[l],总消耗功率:times*cost, f[l][r][1]=f[l][r-1][0] + times*cost;4) f[l][r][1], [l,r-1]->[l,r], time=x[r]-x[r-1],总消耗功率:times*cost, f[l][r][1]=f[l][r-1][1] + times*cost;最终答案:ans = min( f[1][n][0], f[1][n][1] ),关闭长度为 n 的区间,最终可能落位在左端点 1 或者右端点 n 的消耗方案。
*/
const int N = 55;
int n, c;
int x[N], f[N][N][2], sum[N], w[N];int main()
{ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> c;for (int i = 1; i <= n; i++){cin >> x[i] >> w[i];sum[i] = sum[i - 1] + w[i];}/* dp求最小,初始化最大 */memset(f, 0x3f, sizeof f);/* 初始化:开始所在位置的消耗为 0 */f[c][c][0] = f[c][c][1] = 0;/* 枚举区间长度、起点、终点,分情况进行转移*/for (int len = 2; len <= n; len++){for (int l = 1; l + len - 1 <= n; l++){int r = l + len - 1;int cost1 = sum[n] - (sum[r] - sum[l]);                                                                                /* 区间[l+1,r]消耗的功率之和 */int cost2 = sum[n] - (sum[r - 1] - sum[l - 1]);                                                                        /* 区间[l,r-1]消耗的功率之和 */f[l][r][0] = min(f[l][r][0], min(f[l + 1][r][0] + cost1 * (x[l + 1] - x[l]), f[l + 1][r][1] + cost1 * (x[r] - x[l]))); /* 类型 1) */f[l][r][1] = min(f[l][r][1], min(f[l][r - 1][0] + cost2 * (x[r] - x[l]), f[l][r - 1][1] + cost2 * (x[r] - x[r - 1]))); /* 类型 2) */}}cout << min(f[1][n][0], f[1][n][1]) << "\n";return 0;
}
http://www.lryc.cn/news/573495.html

相关文章:

  • Spring Boot + MyBatis + Vue:全栈开发的深度剖析与实践指南
  • IEEE5节点系统潮流仿真模型(simulink+matlab全功能模型)
  • maxcomputer 和 hologres中的EXTERNAL TABLE 和 FOREIGN TABLE
  • Qt/C++应用:防御性编程完全指南
  • C 语言结构体:从基础到内存对齐深度解析
  • 数据结构——函数填空题
  • Rust调用 DeepSeek API
  • Redis 的穿透、雪崩、击穿
  • SuGAR代码精简解读
  • C++ 中 QVector 的判断与操作
  • 探索阿里云容器:解锁云原生应用的无限可能
  • [TPAMI 2022]HGNN: General Hypergraph Neural Networks+
  • Qt + C++ 入门2(界面的知识点)
  • [muduo] ThreadPool | TcpClient | 异步任务 | 通信测试
  • 【单调栈】-----【Largest Rectangle in a Histogram】
  • NuttX Socket 源码学习
  • C++ 第一阶段项目一:实现简易计算器
  • MCPServer编程与CLINE配置调用MCP
  • Taro 状态管理全面指南:从本地状态到全局方案
  • 人工智能学习57-TF训练
  • 逆向入门(16)程序逆向篇-Cabeca
  • 成长笔记——多串口发送与接收
  • Python 数据分析与可视化 Day 3 - Pandas 数据筛选与排序操作
  • springboot垃圾分类网站
  • 关于 Kyber:抗量子密码算法 Kyber 详解
  • 【软考高级系统架构论文】论多源数据集成及应用
  • 组件之间的双向绑定:v-model
  • GitHub OAuth 认证示例
  • 闲庭信步使用SV进行图像处理系列教程介绍
  • 2025年- H83-Lc191--139.单词拆分(动态规划)--Java版