Luogu P1220 关路灯

题目传送门

我\(DP\)太菜了……只会抄题解……

抄了题解的我再来向你们瞎\(\tt{bibi},\) 233~


状态

一道区间\(DP\),我们用dp[i][j]表示将第\(i\)盏路灯到第\(j\)路灯之间的路灯全部关上的最小能耗,但这样我们很难转移,根本无从下手——不知道老张的位置。

既然我们缺少位置信息,那再加上一维不就好了么。于是我们可以用dp[i][j][0/1]表示将第\(i\)盏路灯到第\(j\)路灯之间的路灯全部关上,老张此时在第\(i\)盏路灯下(\(0\))或第\(j\)盏路灯下(\(1\))的最小能耗

那么初始状态很明显就是dp[c][c][1]=dp[c][c][0]=0;

转移

因为我们要快速的求出总区间剔除出一段区间的和,所以可以用前缀和来维护

十分冗长的\(\rm{code}\)

dp[i][j][0]=min(dp[i+1][j][0]+(x[i+1]-x[i])*(sum[n]-sum[j]+sum[i]),dp[i+1][j][1]+(x[j]-x[i])*(sum[n]-sum[j]+sum[i]));
dp[i][j][1]=min(dp[i][j-1][0]+(x[j]-x[i])*(sum[n]-sum[j-1]+sum[i-1]),dp[i][j-1][1]+(x[j]-x[j-1])*(sum[n]-sum[j-1]+sum[i-1]));

\(\mathcal{code}\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int k=0; char c=getchar();
    for(;c<'0'||c>'9';) c=getchar();
    for(;c>='0'&&c<='9';c=getchar())
      k=k*10+c-48;
    return k;
}
int dp[51][51][2],sum[51],x[51];
int main(){
    int n=read(),c=read(); memset(dp,2,sizeof(dp));
    for(int i=1;i<=n;i++) x[i]=read(),sum[i]=sum[i-1]+read();
    dp[c][c][1]=dp[c][c][0]=0;
    for(int j=c;j<=n;j++)
      for(int i=j-1;i;i--){
        dp[i][j][0]=min(dp[i+1][j][0]+(x[i+1]-x[i])*(sum[n]-sum[j]+sum[i]),dp[i+1][j][1]+(x[j]-x[i])*(sum[n]-sum[j]+sum[i]));
        dp[i][j][1]=min(dp[i][j-1][0]+(x[j]-x[i])*(sum[n]-sum[j-1]+sum[i-1]),dp[i][j-1][1]+(x[j]-x[j-1])*(sum[n]-sum[j-1]+sum[i-1]));
      }
    cout<<min(dp[1][n][0],dp[1][n][1]);
    return 0;
}

原文地址:https://www.cnblogs.com/wxl-Ezio/p/9649130.html

时间: 2024-08-03 17:24:47

Luogu P1220 关路灯的相关文章

P1220 关路灯

[P1220]关路灯 - 洛谷 https://www.luogu.org/problem/show?pid=1220 P1220 关路灯 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯

洛谷P1220 关路灯

洛谷1220 关路灯 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯.    为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大

洛谷P1220 关路灯(区间dp)

关路灯 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯.为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边的路

洛谷—— P1220 关路灯

https://www.luogu.org/problem/show?pid=1220 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左

洛谷P1220关路灯[区间DP]

题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边

P1220 关路灯 区间DP

题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边

洛谷P1220关路灯——区间DP

题目:https://www.luogu.org/problemnew/show/P1220 区间DP. 代码如下: #include<iostream> #include<cstdio> using namespace std; int n,c,pos[55],w[55],sum,s[55][55],dp[55][55][3],INF=10000006; int main() { scanf("%d%d",&n,&c); for(int i=1

P1220 关路灯(区间规划)

题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电.他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯.开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边

codevs1258 关路灯(☆区间dp)

1258 关路灯 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 多瑞卡得到了一份有趣而高薪的工作.每天早晨他必须关掉他所在村庄的街灯.所有的街灯都被设置在一条直路的同一侧. 多瑞卡每晚到早晨5点钟都在晚会上,然后他开始关灯.开始时,他站在某一盏路灯的旁边. 每盏灯都有一个给定功率的电灯泡,因为多端卡有着自觉的节能意识,他希望在耗能总数最少的情况下将所有的灯关掉. 多端卡因为太累了,所以只能以1m/s的速度行走.关灯不需要花