1. 程式人生 > >洛谷 1220 關路燈

洛谷 1220 關路燈

pac 轉移 src 技術分享 正在 區間dp esp 除了 回憶

技術分享圖片技術分享圖片

一道典型的區間dp題

我一開始做的時候,忘記了之前是怎麽寫這道題的了

於是翻開之前的代碼

回憶起了這題的大致思路

dp[i][j][0/1]

表示i~j區間,0表示老張現在正在區間的i端,1表示老張正在區間的j端

我們想一下怎麽轉移

肯定是由i+1,j或者i,j-1轉移過來的

那麽我們只要計算一下除了i+1,j區間之外的還亮著的耗能,和i,j-1區間之外的還亮著的耗能

這個計算很簡單,只需要計算一下前綴和就可以算出來了

我們看看代碼

 1 #include <cstdio>//0在i,1在j
 2 #include <cstdlib>
 3 #include <iostream>
 4
#include <algorithm> 5 #include <cstring> 6 #include <iostream> 7 using namespace std; 8 const int N=1000; 9 int sum[N],p[N],d[N],n,c,dp[N][N][2]; 10 int calc(int a,int b,int i,int j) 11 { 12 return (p[b]-p[a])*(sum[i]+sum[n]-sum[j]); 13 } 14 int main() 15 { 16 scanf("%d %d
",&n,&c); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d %d",&p[i],&d[i]); 20 sum[i]=sum[i-1]+d[i]; 21 } 22 memset(dp,0x3f,sizeof(dp)); 23 dp[c][c][0]=dp[c][c][1]=0; 24 for(int i=c;i<=n;i++) 25 { 26 for(int j=i-1;j>=1;j--) 27 {
28 dp[j][i][0]=min(dp[j+1][i][1]+calc(j,i,j,i),dp[j+1][i][0]+calc(j,j+1,j,i)); 29 dp[j][i][1]=min(dp[j][i-1][0]+calc(j,i,j-1,i-1),dp[j][i-1][1]+calc(i-1,i,j-1,i-1)); 30 } 31 } 32 printf("%d\n",min(dp[1][n][0],dp[1][n][1])); 33 return 0; 34 }

一開始不要忘記賦初始值0

洛谷 1220 關路燈