節能(區間DP)

描述:

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

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

機器人卡多以1m/s的速度行走。假設關燈動作不需要花費額外的時間,因爲當它通過某盞路燈時就順手將燈關掉。

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


輸入:

第一行:N表示ZK大道右側路燈的數量          (2≤ N ≤ 1000) 

第二行:V表示機器人卡多開始關燈的路燈號碼。   (1≤V≤N)

接下來的N行中,每行包含兩個用空格隔開的整數DW,用來描述每盞燈的參數

D表示該路燈與ZK大道起點的距離  (用米爲單位來表示),

W表示燈泡的功率,即每秒該燈泡所消耗的能量數。路燈是按順序給定的。

( 0≤D≤1000, 0≤W≤1000 )


輸出:

輸出一個整數,即消耗能量之和的最小值。注意結果小於200,000,000


樣例輸入:


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;
} 


發佈了31 篇原創文章 · 獲贊 27 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章