題目描述
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小(即同一段時間內消耗的電量有多有少)。老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。
為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電。他每天都是在天亮時首先關掉自己所處位置的路燈,然後可以向左也可以向右去關燈。開始他以為先算一下左邊路燈的總功率再算一下右邊路燈的總功率,然後選擇先關掉功率大的一邊,再回過頭來關掉另一邊的路燈,而事實並非如此,因為在關的過程中適當地調頭有可能會更省一些。
現在已知老張走的速度為1m/s,每個路燈的位置(是乙個整數,即距路線起點的距離,單位:m)、功率(w),老張關燈所用的時間很短而可以忽略不計。
請你為老張編一程式來安排關燈的順序,使從老張開始關燈時刻算起所有燈消耗電最少(燈關掉後便不再消耗電了)。
輸入輸出格式
輸入格式:
檔案第一行是兩個數字n(0 < n < 50,表示路燈的總數)和c(1<=c<=n老張所處位置的路燈號);
接下來n行,每行兩個資料,表示第1盞到第n盞路燈的位置和功率。
輸出格式:
乙個資料,即最少的功耗(單位:j,1j=1w·s)。
輸入輸出樣例
輸入樣例#1:
5 3
2 10
3 20
5 20
6 30
8 10
輸出樣例#1:
270
說明 輸出解釋:
分析:注意功率做乙個字首和
f[i][j][0]表示關掉i,j這段區間的燈,並且老張在區間的左邊的最小花費
f[i][j][1]表示關掉i,j這段區間的燈,並且老張在區間的右邊的最小花費
顯然 f[i][j][0] 可以從 [i+1][j][0]向左走乙個燈 也可以從[i+1][j][1]向左走過一段區間來到這裡
轉移方程:
f[i][j][0]=min((pos[i+1]-pos[i]) * (pst[n]-pst[j]+pst[i])+f[i+1][j][0],(pos[j]-pos[i]) * (pst[n]-pst[j]+pst[i])+f[i+1][j][1]);
f[i][j][1]=min((pos[j]-pos[j-1]) * (pst[n]-pst[j-1]+pst[i-1])+f[i][j-1][1],(pos[j]-pos[i]) * (pst[n]-pst[j-1]+pst[i-1])+f[i][j-1][0]);
#include
#include
#include
#include
using namespace std;
#define maxn 55
int f[maxn][maxn][2],n,c,pos[maxn],pst[maxn],ans;
inline void read(int &x)
while(c>='0'&&c<='9') x
*=f;
}int main()
memset(f,0x3f,sizeof f );
f[c][c][0]=f[c][c][1]=0;
for(int k=1;kint
s=max(0,c-k),t=min(n,k+c);
for(int i=s;i<=t;++i)
}ans=min(f[1][n][0],f[1][n][1]);
printf("%d\n",ans);
return0;}
int aptal_is_my_son=main();
int main(int argc,char *argv)
洛谷 P1220 關路燈
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...
洛谷 P1220 關路燈
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...
洛谷 P1220 關路燈
原本想用搜尋先超時一把 然後發現剪枝居然過了 include include include include include include using namespace std int d 10005 記錄燈的功率 int lef,righ,minx int run int x,int y 記錄...