節能
點擊開啟題目
時間限制: 1000 ms | 記憶體限制: 65535 KB 難度:5 描述
Dr.Kong設計的機器人卡多越來越聰明。最近市政公司交給卡多一項任務,每天早晨5:00開始,它負責關掉ZK大道右側上所有的路燈。
卡多每到早晨5:00準會在ZK大道上某盞路燈的旁邊,然後他開始關燈。每盞燈都有一定的功率,機器人卡多有著自覺的節能意識,它希望在關燈期間,ZK大道右側上所有路燈的耗電量總數是最少的。
機器人卡多以1m/s的速度行走。假設關燈動作不需要花費額外的時間,因為當它通過某盞路燈時就順手將燈關掉。
請你編寫程式,計算在給定路燈設定,燈泡功率以及機器人卡多的起始位置的情況下,卡多關燈期間,ZK大道上所有燈耗費的最小能量。 輸入 有多組測試資料,以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 32 25 86 18 7
範例輸出
56
來源
第四屆河南省程式設計大賽
解題思路:
本題是一道Dynamic Programming的題目,機器人關燈要麼是去左邊關燈,或者是去右邊關燈,也即要關閉的下一個路燈要麼是從已關閉路段的左端過去的,要麼是從已關閉的路段的右端過去的,定義:
DP[i][j][0]表示i到j的路燈都已經關閉,機器人在路燈i的位置,此時已經消耗的最小電能
DP[i][j][1]表示i到j的路燈都已經關閉,機器人在路燈j的位置,此時已經消耗的最小電能
則狀態轉移式:
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期間消耗的電能)
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期間消耗的電能)
(注意:dp中的i,j區間表示的不是距離,而是第幾個燈,如第 i 個燈到第 j 個燈)
AC代碼:
#include<bits/stdc++.h>using namespace std;const int MAX=1e3+10;const int INF=0x3f3f3f3f;struct {int d,w;}node[MAX];int dp[MAX][MAX][2];//DP[i][j][0]表示i到j的路燈都已經關閉,機器人在路燈i的位置,此時已經消耗的最小電能//DP[i][j][1]表示i到j的路燈都已經關閉,機器人在路燈j的位置,此時已經消耗的最小電能int bw[MAX][MAX];//儲存從 i 到 j 這個區間的路燈功率消耗總數; int main(){int n;while(cin>>n){int v;cin>>v;int tw=0;//紀錄所有燈的功率 for(int i=1;i<=n;i++){scanf("%d %d",&node[i].d,&node[i].w);tw+=node[i].w;}memset(bw,0,sizeof(bw));//初始化 for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){bw[i][j]=bw[i][j-1]+node[j].w;}}for(int i=v-1;i>0;i--){dp[i][v][0]=dp[i+1][v][0]+(tw-bw[i+1][v])*(node[i+1].d-node[i].d);dp[i][v][1]=dp[i][v][0]+(tw-bw[i][v])*(node[v].d-node[i].d);}for(int i=v+1;i<=n;i++){dp[v][i][1]=dp[v][i-1][1]+(tw-bw[v][i-1])*(node[i].d-node[i-1].d);dp[v][i][0]=dp[v][i][1]+(tw-bw[v][i])*(node[i].d-node[v].d);}//dp狀態轉化 for(int i=v-1;i>0;i--){for(int j=v+1;j<=n;j++){dp[i][j][0]=min(dp[i+1][j][0]+(tw-bw[i+1][j])*(node[i+1].d-node[i].d),dp[i+1][j][1]+(tw-bw[i+1][j])*(node[j].d-node[i].d));dp[i][j][1]=min(dp[i][j-1][1]+(tw-bw[i][j-1])*(node[j].d-node[j-1].d),dp[i][j-1][0]+(tw-bw[i][j-1])*(node[j].d-node[i].d));}}cout<<min(dp[1][n][0],dp[1][n][1])<<endl;}return 0;}