描述:
Dr.Kong設計的機器人卡多越來越聰明。最近市政公司交給卡多一項任務,每天早晨5:00開始,它負責關掉ZK大道右側上所有的路燈。
卡多每到早晨5:00準會在ZK大道上某盞路燈的旁邊,然後他開始關燈。每盞燈都有一定的功率,機器人卡多有着自覺的節能意識,它希望在關燈期間,ZK大道右側上所有路燈的耗電量總數是最少的。
機器人卡多以1m/s的速度行走。假設關燈動作不需要花費額外的時間,因爲當它通過某盞路燈時就順手將燈關掉。
請你編寫程序,計算在給定路燈設置,燈泡功率以及機器人卡多的起始位置的情況下,卡多關燈期間,ZK大道上所有燈耗費的最小能量。
第一行: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
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1005][1005][2]; //dp[i][j][0]表示由區間i,j之間最後達到i位置時的耗電量 ,dp[i][j][1]表示由區間i,j之間最後達到j位置時的耗電量
int asd[1005][1005],num,pos,totle=0;; //asd[i][j]數組表示從i位置到j位置初始狀態下的功率總耗
struct asd
{
int dis;
int w;
}gw[1005];
void sove()
{
for(int i=pos-1;i>0;i--) //分兩部分考慮一部分是1——起始位置另一部分是起始位置到num
{
dp[i][pos][0]=dp[i+1][pos][0]+(totle-asd[i+1][pos])/*該段時間內消耗的功率*/*(gw[i+1].dis-gw[i].dis)/*兩種狀態下的位置差即爲所用時間*/;
dp[i][pos][1]=dp[i][pos][0]+(totle-asd[i][pos])*(gw[pos].dis-gw[i].dis); //轉換最後的終點位置,只需求出起始位置到i位置所需的時間和這段時間內消耗的功率
}
for(int i=pos+1;i<=num;i++) //同理這是第二種情況
{
dp[pos][i][1]=dp[pos][i-1][1]+(totle-asd[pos][i-1])*(gw[i].dis-gw[i-1].dis);
dp[pos][i][0]=dp[pos][i][1]+(totle-asd[pos][i])*(gw[i].dis-gw[pos].dis);
}
for(int i=pos-1;i>=1;i--)
{
for(int j=pos+1;j<=num;++j)
{
dp[i][j][0]=min(dp[i+1][j][0]+(totle-asd[i+1][j])*(gw[i+1].dis-gw[i].dis),dp[i+1][j][1]+(totle-asd[i+1][j])*(gw[j].dis-gw[i].dis));
dp[i][j][1]=min(dp[i][j-1][0]+(totle-asd[i][j-1])*(gw[j].dis-gw[i].dis),dp[i][j-1][1]+(totle-asd[i][j-1])*(gw[j].dis-gw[j-1].dis));
}
}
}
int main()
{
scanf("%d %d",&num,&pos);
for(int i=1;i<=num;i++)
{
scanf("%d %d",&gw[i].dis,&gw[i].w);
totle+=gw[i].w; //求出初始狀態下的功率總耗
}
memset(dp,0,sizeof(dp));
memset(asd,0,sizeof(asd)); //初始化兩個數組
for(int i=1;i<=num;++i) //計算從i位置到j位置初始狀態下的功率總耗
{
for(int j=i;j<=num;++j)
{
asd[i][j]=asd[i][j-1]+gw[j].w;
}
}
sove();
printf("%d\n",min(dp[1][num][0],dp[1][num][1]));
return 0;
}