1. 程式人生 > >BZOJ 1617 [Usaco2008 Mar]River Crossing渡河問題:dp

BZOJ 1617 [Usaco2008 Mar]River Crossing渡河問題:dp

tdi std pro usaco2008 targe ans space cost swe

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1617

題意:

  Farmer John以及他的N(1 <= N <= 2,500)頭奶牛打算過一條河,但他們所有的渡河工具,僅僅是一個木筏。

  由於奶牛不會劃船,在整個渡河過程中,FJ必須始終在木筏上。

  在這個基礎上,木筏上的奶牛數目每增加1,FJ把木筏劃到對岸就得花更多的時間。當FJ一個人坐在木筏上,他把木筏劃到對岸需要M(1 <= M <= 1000)分鐘。當木筏搭載的奶牛數目從i-1增加到i時,FJ得多花M_i(1 <= M_i <= 1000)分鐘才能把木筏劃過河(也就是說,船上有1頭奶牛時,FJ得花M+M_1分鐘渡河;船上有2頭奶牛時,時間就變成M+M_1+M_2分鐘。後面的依此類推)。

  那麽,FJ最少要花多少時間,才能把所有奶牛帶到對岸呢?當然,這個時間得包括FJ一個人把木筏從對岸劃回來接下一批的奶牛的時間。

題解:

  表示狀態:

    dp[i] = min cost time

    i:已經運送了i只奶牛,並且FJ回到了河的這邊。

  找出答案:

    ans = dp[n] - m

    最後一趟不用再回來,所以 - M。

  如何轉移:

    dp[i+j] = min dp[i] + sum[j] + M

    枚舉每一次運送j只牛,sum為一次性運送j只牛花費的時間。

    因為還要一個人回來,所以還要 + M。

  邊界條件:

    dp[0] = 0

AC Code:

 1 // state expression:
 2 // dp[i] = min cost time
 3 // i: i cows have been transed
 4 //
 5 // find the answer:
 6 // ans = dp[n] - M
 7 //
 8 // transferring:
 9 // dp[i+j] = min dp[i] + sum[j] + M
10 //
11 // boundary:
12 // dp[0] = 0
13 #include <iostream>
14 #include <stdio.h>
15 #include <string
.h> 16 #define MAX_N 2505 17 18 using namespace std; 19 20 int n,m; 21 int t[MAX_N]; 22 int sum[MAX_N]; 23 int dp[MAX_N]; 24 25 void read() 26 { 27 cin>>n>>m; 28 for(int i=1;i<=n;i++) 29 { 30 cin>>t[i]; 31 } 32 } 33 34 void solve() 35 { 36 sum[0]=2*m; 37 for(int i=1;i<=n;i++) 38 { 39 sum[i]=sum[i-1]+t[i]; 40 } 41 memset(dp,0x3f,sizeof(dp)); 42 dp[0]=0; 43 for(int i=0;i<n;i++) 44 { 45 for(int j=1;i+j<=n;j++) 46 { 47 dp[i+j]=min(dp[i+j],dp[i]+sum[j]); 48 } 49 } 50 } 51 52 void print() 53 { 54 cout<<dp[n]-m<<endl; 55 } 56 57 int main() 58 { 59 read(); 60 solve(); 61 print(); 62 }

BZOJ 1617 [Usaco2008 Mar]River Crossing渡河問題:dp