zoukankan      html  css  js  c++  java
  • 洛谷 P1220 关路灯(区间dp,前缀和)

    传送门


    解题思路

    先明确一下题意,c指的是路灯的编号而不是位置。

    然后根据贪心,在从点i去关点j的路灯时,所有经过的路灯都会随手关掉(不耗时间),所以我们可以确定,若i点和j点的路灯已经关闭,那么区间i...j的路灯已经全部关闭,而且关完后,最优策略一定是在点i处或者点j处。

    这和上一题就很像了,用dp[i][j]表示把区间i...j的路灯全部关闭所有的最小电量。然后dp[i][j][0]表示关完后在i点时的最小电量,dp[i][j][1]表示关完后在j点时的最小电量。

    最后想一下动态转移方程,dp[i][j][0]可以从dp[i+1][j][0]和dp[i+1][j][1]转移而来,dp[i][j][1]可以从dp[i][j-1][0]和dp[i][j-1][1]转移而来。

    怎样计算呢?很显然是原来的dp值再加上关第i盏灯或第j盏灯要付出的代价。

    代价怎么求?

    我们很显然能作差求出距离(所用的时间),我们还需要知道到目前为止剩下的还未关的灯的功率和,因为已经关了的灯一定在某一区间内,然后又要求和,所以很自然地就想到了前缀和。

    最后的最后,last but not least,重要的事情说三遍:

    细节,细节,细节!

    AC代码

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int n,a[105],w[105],dp[105][105][2],now,sum[105];
     5 int main()
     6 {
     7     cin>>n>>now;
     8     memset(dp,0x3f,sizeof(dp));
     9     for(int i=1;i<=n;i++){
    10         cin>>a[i]>>w[i];
    11         sum[i]=sum[i-1]+w[i];
    12     }
    13     dp[now][now][0]=dp[now][now][1]=0;
    14     for(int len=2;len<=n;len++){
    15         for(int i=max(1,now-len+1);i<=min(now,n);i++){
    16             int j=i+len-1;
    17             if(j>n) break;
    18             dp[i][j][0]=min(dp[i+1][j][0]+(sum[i]+sum[n]-sum[j])*(a[i+1]-a[i]),dp[i+1][j][1]+(sum[i]+sum[n]-sum[j])*(a[j]-a[i]));
    19             dp[i][j][1]=min(dp[i][j-1][0]+(sum[i-1]+sum[n]-sum[j-1])*(a[j]-a[i]),dp[i][j-1][1]+(sum[i-1]+sum[n]-sum[j-1])*(a[j]-a[j-1]));
    20         }
    21     }
    22     cout<<min(dp[1][n][0],dp[1][n][1]);
    23     return 0;
    24 }
  • 相关阅读:
    XML学习教程
    JSON 的含义?
    局域网共享问题全方位解决
    VMware虚拟化培训手册
    信息化建设中的IT规划精要
    洛谷1265 公路修建
    洛谷1144 最短路计数
    NOI题库05 派
    NOI题库7624 山区建小学(162:Post Office / IOI2000 POST OFFICE [input] )
    vijosP1014 旅行商简化版
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12375381.html
Copyright © 2011-2022 走看看