區間dp, 考慮設\(dp[i][j][t]\)為已經關掉了\([i,j]\)的電燈, 人在t端點處時的最小代價
可以推出方程:
\[dp[i+1][j][0]+(p[n]-p[j]+p[i])*(loc[i+1]-loc[i]) -> dp[i][j][0]
\]\[dp[i][j-1][0]+(p[n]-p[j-1]+p[i-1])*(loc[j]-loc[i]) -> dp[i][j][1]
\]\[dp[i][j-1][1]+(p[n]-p[j-1]+p[i-1])*(loc[j]-loc[j-1]) -> dp[i][j][1]
\]\[dp[i+1][j][1]+(p[n]-p[j]+p[i])*(loc[j]-loc[i]) -> dp[i][j][0]
\]直接dp... 且慢, 順序是什麼...... 好像很麻煩的樣子......
但是其實可以不用考慮順序問題的, 一位超強的選手\(wyx\)說過:
\(\text\)
如果採用記憶化搜尋, 啥都不用想一頓碼, 碼完ac, 極其快樂, 比那些dp不知道高到**去了
code:
#define f(i,x,y) for(int i=x,i##end=y;i<=i##end;++i)
#define d(i,x,y) for(int i=x,i##end=y;i>=i##end;--i)
#define ri register int
#define ll long long
#define il inline
namespace intio void read(int& x) }; using namespace intio;
int max(int x, int y) int min(int x, int y)
int main(){
memset(dp, 0x3f, sizeof(dp)) ;
scanf("%d%d",&n,&c) ;
f(i,1,n) scanf("%d%d", &loc[i], &p[i]), p[i] += p[i-1] ;
dp[c][c][1] = dp[c][c][0] = 0 ;
work(1,n);
cout<
P1220關路燈(題解)
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...
洛谷 題解 P1220 關路燈
搜尋 inline void dfs int now,int l,int r,int cnt,int sum,int k now為當前點 l為左端點 r為右端點 cnt為當前耗電量 sum為開著的燈的總耗電 k為還有幾盞燈開著 if l 1 dfs l 1,l 1,r,cnt m now m l 1...
P1220 關路燈 提高
以下內容 z2415445508 只是為了方便自己複習而已 題目傳送門 關路燈 關燈不需要額外的時間,經過了燈就關了。但是可能折返回去關某乙個大燈會比繼續往下走關接下來的乙個小燈更優,那麼可以得到兩種狀態 沿著當前方向繼續往下走,改變方向回去關燈 我們需要得到的整個關燈過程中的最優值 最小耗能 那麼...