洛谷傳送門
某一村莊在一條路線上安裝了 nn 盞路燈,每盞燈的功率有大有小(即同一段時間內消耗的電量有多有少)。老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。
為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電。他每天都是在天亮時首先關掉自己所處位置的路燈,然後可以向左也可以向右去關燈。開始他以為先算一下左邊路燈的總功率再算一下右邊路燈的總功率,然後選擇先關掉功率大的一邊,再回過頭來關掉另一邊的路燈,而事實並非如此,因為在關的過程中適當地調頭有可能會更省一些。
現在已知老張走的速度為 1m/s1m/s,每個路燈的位置(是乙個整數,即距路線起點的距離,單位:mm)、功率(ww),老張關燈所用的時間很短而可以忽略不計。
請你為老張編一程式來安排關燈的順序,使從老張開始關燈時刻算起所有燈消耗電最少(燈關掉後便不再消耗電了)。
第一行是兩個數字 nn(表示路燈的總數)和 cc(老張所處位置的路燈號);
接下來 nn 行,每行兩個資料,表示第 11 盞到第 nn 盞路燈的位置和功率。資料保證路燈位置單調遞增。
乙個資料,即最少的功耗(單位:jj,1j=1w\times s1j=1w×s)。
看看這資料範圍,慌不慌
模擬usacothe cow run的題目來做。
性質還是差不多一樣的。他在關完一盞燈之後,可以選擇折返關燈,也可以選擇繼續往下去關。所以這個dp的轉移需要兩個狀態。乙個表示\(0\)關完所有燈之後站在左端點,乙個表示\(1\)關完燈之後站在右端點。
最後的答案就是\(\min(dp[1][n][0],dp[1[n][1]])\)
轉移好好想想就能想出來,每次的決策就是回頭或者不回頭。
然後每次轉移的時候計算一下消耗功率,這個用字首和維護即可:
**:
#include#include#includeusing namespace std;
const int maxn=60;
int a[maxn],b[maxn],sum[maxn],n,m,c;
int dp[maxn][maxn][2];
int main()
dp[c][c][0]=dp[c][c][1]=0;
for(int len=2;len<=n;len++)
for(int i=1;i+len-1<=n;i++)
int ans=min(dp[1][n][0],dp[1][n][1]);
printf("%d",ans);
return 0;
}
洛谷 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 記錄...