1. 程式人生 > >P2904 [USACO08MAR]跨河River Crossing

P2904 [USACO08MAR]跨河River Crossing

include cow mine 最小值 pac 一個人 amp ride esp

P2904 [USACO08MAR]跨河River Crossing

題目描述

Farmer John is herding his N cows (1 <= N <= 2,500) across the expanses of his farm when he finds himself blocked by a river. A single raft is available for transportation.

FJ knows that he must ride on the raft for all crossings and that that adding cows to the raft makes it traverse the river more slowly.

When FJ is on the raft alone, it can cross the river in M minutes (1 <= M <= 1000). When the i cows are added, it takes M_i minutes (1 <= M_i <= 1000) longer to cross the river than with i-1 cows (i.e., total M+M_1 minutes with one cow, M+M_1+M_2 with two, etc.). Determine the minimum time it takes for Farmer John to get all of the cows across the river (including time returning to get more cows).

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一個人把木筏從對岸劃回來接下一批的奶牛的時間。

輸入輸出格式

輸入格式:

  • Line 1: Two space-separated integers: N and M

  • Lines 2..N+1: Line i+1 contains a single integer: M_i

輸出格式:

  • Line 1: The minimum time it takes for Farmer John to get all of the cows across the river.

輸入輸出樣例

輸入樣例#1:
5 10 
3 
4 
6 
100 
1 
輸出樣例#1:
50 

說明

There are five cows. Farmer John takes 10 minutes to cross the river alone, 13 with one cow, 17 with two cows, 23 with three, 123 with four, and 124 with all five.

Farmer John can first cross with three cows (23 minutes), then return (10 minutes), and then cross with the last two (17 minutes). 23+10+17 = 50 minutes total.

動規: f[i] 是運過第 i 頭牛後最少的時間,所以我們枚舉所有小於等於 i 的數 j,就是先送過(i-j)頭牛,再送剩余的牛,取最小值。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 const int N = 3010;
 7 
 8 int f[N];
 9 int sum[N];
10 int n,m;
11 
12 int main()
13 {
14     scanf("%d%d",&n,&m);
15     for(int i=1;i<=n;++i)
16     {
17         scanf("%d",&sum[i]);
18         sum[i] += sum[i-1];
19         f[i] = sum[i]+m;
20     }
21     for(int i=1;i<=n;++i) sum[i] += m;
22     for(int i=2;i<=n;++i)
23     {
24         for(int j=1;j<=i;++j)
25         {
26             f[i] = min(f[i],f[j]+sum[i-j]+m);
27         }
28     }
29     printf("%d",f[n]);
30     return 0;
31 }

有一點難看。稍微改了一下這樣寫的

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 const int N = 3010;
 7 
 8 int f[N];
 9 int sum[N];
10 int n,m;
11 
12 int main()
13 {
14     scanf("%d%d",&n,&m);
15     for(int i=1;i<=n;++i)
16     {
17         scanf("%d",&sum[i]);
18         sum[i] += sum[i-1];
19     }
20     for(int i=1;i<=n;++i) 
21     {
22         sum[i] += m;
23         f[i] = sum[i];
24     }
25     for(int i=2;i<=n;++i)
26     {
27         for(int j=1;j<=i;++j)
28         {
29             f[i] = min(f[i],f[j]+sum[i-j]+m);
30         }
31     }
32     printf("%d",f[n]);
33     return 0;
34 }

P2904 [USACO08MAR]跨河River Crossing