nyoj304 節能

節能

時間限制:1000 ms  |  內存限制:65535 KB
難度:5
描述

Dr.Kong設計的機器人卡多愈來愈聰明。最近市政公司交給卡多一項任務,天天早晨5:00開始,它負責關掉ZK大道右側上全部的路燈。php

卡多每到早晨5:00準會在ZK大道上某盞路燈的旁邊,而後他開始關燈。每盞燈都有必定的功率,機器人卡多有着自覺的節能意識,它但願在關燈期間,ZK大道右側上全部路燈的耗電量總數是最少的。ios

機器人卡多以1m/s的速度行走。假設關燈動做不須要花費額外的時間,由於當它經過某盞路燈時就順手將燈關掉。測試

請你編寫程序,計算在給定路燈設置,燈泡功率以及機器人卡多的起始位置的狀況下,卡多關燈期間,ZK大道上全部燈耗費的最小能量。spa

輸入
有多組測試數據,以EOF爲輸入結束的標誌
每組測試數據第一行: N 表示ZK大道右側路燈的數量 (2≤ N ≤ 1000)
第二行: V 表示機器人卡多開始關燈的路燈號碼。 (1≤V≤N)
接下來的N行中,每行包含兩個用空格隔開的整數D和W,用來描述每盞燈的參數

D表示該路燈與ZK大道起點的距離 (用米爲單位來表示),
W表示燈泡的功率,即每秒該燈泡所消耗的能量數。路燈是按順序給定的。
( 0≤D≤1000, 0≤W≤1000 )
輸出
輸出一個整數,即消耗能量之和的最小值。注意結果小於200,000,000
樣例輸入
4 
3
2 2
5 8
6 1
8 7
樣例輸出
56
來源
第四屆河南省程序設計大賽

解題思路:.net

本題是一道Dynamic Programming的題目,機器人關燈要麼是去左邊關燈,或者是去右邊關燈,也即要關閉的下一個路燈要麼是從已關閉路段的左端過去的,要麼是從已關閉的路段的右端過去的,定義:設計

DP[i][j][0]表示i到j的路燈都已經關閉,機器人在路燈i的位置,此時已經消耗的最小電能code

DP[i][j][1]表示i到j的路燈都已經關閉,機器人在路燈j的位置,此時已經消耗的最小電能blog

則狀態轉移式:內存

DP[i][j][0] = min(DP[i+1][j][0]+[i+1,j]路段之外未關閉路燈在機器人從i+1走的i期間消耗的電能,DP[i+1][j][1]+[i+1,j]路段之外未關閉路燈在機器人從j走到i期間消耗的電能)get

DP[i][j][1] = min(DP[i][j-1][0]+[i,j-1]路段之外未關閉路燈在機器人從i走到j期間消耗的電能,DP[i][j-1][1]+[i,j-1]路段之外未關閉路燈在機器人從j-1走到j期間消耗的電能)


AC代碼:

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 const int N = 1010;
 7 int dp[N][N][2],dw[N][N],st[N],co[N];
 8 int main()
 9 {
10     int n,s,v,sum;
11     while(scanf("%d",&n)!=EOF)
12     {
13         memset(dw,0,sizeof(dw));
14         sum = 0;
15         scanf("%d",&v);
16         for(int i =1; i<=n; i++)
17         {
18             scanf("%d %d",&st[i],&co[i]);
19             sum =sum+co[i];
20         }
21         for(int i=1;i<=n;i++)
22             for(int j=i;j<=n;j++)
23               dw[i][j] = dw[i][j-1]+co[j];
24         for(int i = v-1; i>0; i--)
25         {
26             dp[i][v][0] = dp[i+1][v][0]+(sum-dw[i+1][v])*(st[i+1]-st[i]);
27             dp[i][v][1] = dp[i][v][0] +(sum-dw[i][v])*(st[v]-st[i]);
28         }
29         for(int j =v+1; j<=n; j++)
30         {
31             dp[v][j][1] =dp[v][j-1][1]+(sum-dw[v][j-1])*(st[j]-st[j-1]);
32             dp[v][j][0] =dp[v][j][1]+(sum-dw[v][j])*(st[j]-st[v]);
33         }
34 
35         for(int i =v-1;i>0;i--)
36         {
37             for(int j =v+1; j<=n; j++)
38             {
39                 dp[i][j][0] = min(dp[i+1][j][0]+(sum-dw[i+1][j])*(st[i+1]-st[i]),
40                                   dp[i+1][j][1]+(sum-dw[i+1][j])*(st[j]-st[i]));
41                 dp[i][j][1] = min(dp[i][j-1][0]+(sum-dw[i][j-1])*(st[j]-st[i]),
42                                   dp[i][j-1][1]+(sum-dw[i][j-1])*(st[j]-st[j-1]));
43             }
44         }
45 
46         printf("%d\n", min(dp[1][n][0], dp[1][n][1]));
47     }
48     return 0;
49 }
相關文章
相關標籤/搜索