BZOJ 1617 [Usaco2008 Mar]River Crossing渡河问题:dp
Posted Leohh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1617 [Usaco2008 Mar]River Crossing渡河问题:dp相关的知识,希望对你有一定的参考价值。
题目链接: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的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1617 [Usaco2008 Mar]River Crossing渡河问题:dp
BZOJ 1617 Usaco 2008 Mar. River Crossing渡河问题
1617: [Usaco2008 Mar]River Crossing渡河问题(dp)