解題思路:
本題是一道Dynamic Programming的題目,機器人關燈要麼是去左邊關燈,或者是去右邊關燈,也即要關閉的下一個路燈要麼是從已關閉路段的左端過去的,要麼是從已關閉的路段的右端過去的,定義:
DP[i][j][0]表示i到j的路燈都已經關閉,機器人在路燈i的位置,此時已經消耗的最小電能
DP[i][j][1]表示i到j的路燈都已經關閉,機器人在路燈j的位置,此時已經消耗的最小電能
則狀態轉移式:
DP[i][j][0] = min(DP[i+1][j][0]+[i+1,j]路段以外未關閉路燈在機器人從i+1走的i期間消耗的電能,DP[i+1][j][1]+[i+1,j]路段以外未關閉路燈在機器人從j走到i期間消耗的電能)
DP[i][j][1] = min(DP[i][j-1][0]+[i,j-1]路段以外未關閉路燈在機器人從i走到j期間消耗的電能,DP[i][j-1][1]+[i,j-1]路段以外未關閉路燈在機器人從j-1走到j期間消耗的電能)
AC代碼:
1 #include<algorithm> 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 using namespace std; 6 const int N = 1010; 7 int dp[N][N][2],dw[N][N],st[N],co[N]; 8 int main() 9 {10 int n,s,v,sum;11 while(scanf("%d",&n)!=EOF)12 {13 memset(dw,0,sizeof(dw));14 sum = 0;15 scanf("%d",&v);16 for(int i =1; i<=n; i++)17 {18 scanf("%d %d",&st[i],&co[i]);19 sum =sum+co[i];20 }21 for(int i=1;i<=n;i++)22 for(int j=i;j<=n;j++)23 dw[i][j] = dw[i][j-1]+co[j];24 for(int i = v-1; i>0; i--)25 {26 dp[i][v][0] = dp[i+1][v][0]+(sum-dw[i+1][v])*(st[i+1]-st[i]);27 dp[i][v][1] = dp[i][v][0] +(sum-dw[i][v])*(st[v]-st[i]);28 }29 for(int j =v+1; j<=n; j++)30 {31 dp[v][j][1] =dp[v][j-1][1]+(sum-dw[v][j-1])*(st[j]-st[j-1]);32 dp[v][j][0] =dp[v][j][1]+(sum-dw[v][j])*(st[j]-st[v]);33 }34 35 for(int i =v-1;i>0;i--)36 {37 for(int j =v+1; j<=n; j++)38 {39 dp[i][j][0] = min(dp[i+1][j][0]+(sum-dw[i+1][j])*(st[i+1]-st[i]),40 dp[i+1][j][1]+(sum-dw[i+1][j])*(st[j]-st[i]));41 dp[i][j][1] = min(dp[i][j-1][0]+(sum-dw[i][j-1])*(st[j]-st[i]),42 dp[i][j-1][1]+(sum-dw[i][j-1])*(st[j]-st[j-1]));43 }44 }45 46 printf("%d\n", min(dp[1][n][0], dp[1][n][1]));47 }48 return 0;49 }