题目链接
题面
题目描述
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).
F
a
r
m
e
r
Farmer
Farmer
J
o
h
n
John
John以及他的
N
(
1
<
=
N
<
=
2
,
500
)
N(1 <= N <= 2,500)
N(1<=N<=2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏。 由于奶牛不会划船,在整个渡河过程中,
F
J
FJ
FJ 必须始终在木筏上。在这个基础上,木筏上的奶牛数目每增加
1
1
1,
F
J
FJ
FJ 把木筏划到对岸就得花更多的时间。 当
F
J
FJ
FJ 一个人坐在木筏上,他把木筏划到对岸需要
M
(
1
<
=
M
<
=
1000
)
M(1 <= M <= 1000)
M(1<=M<=1000) 分钟。当木筏搭载的奶牛数目从
i
−
1
i-1
i−1 增加到
i
i
i 时,
F
J
FJ
FJ 得多花
M
i
(
1
<
=
M
i
<
=
1000
)
M_i(1 <= M_i <= 1000)
Mi(1<=Mi<=1000) 分钟才能把木筏划过河(也就是说,船上有
1
1
1 头奶牛时,
F
J
FJ
FJ 得花
M
+
M
1
M+M_1
M+M1 分钟渡河;船上有
2
2
2 头奶牛时,时间就变成
M
+
M
1
+
M
2
M+M_1+M_2
M+M1+M2 分钟。后面的依此类推)。那么,
F
J
FJ
FJ 最少要花多少时间,才能把所有奶牛带到对岸呢?当然,这个时间得包括
F
J
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
样例输入 #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.
题意
- 有 n n n 只奶牛要过河
- 船上只有 F J FJ FJ 时过一次河需要 M M M 分钟
- 若有 p p p 只奶牛坐船过一次河,需要多花 m 1 + m 2 + ⋯ + m p m_1+m_2+\dots +m_p m1+m2+⋯+mp 分钟才能过河
- 求最少需要多少分钟才能让 F J FJ FJ 和他的奶牛全部过河
思路
定义 q z h qzh qzh 数组为 m m m 数组的前缀和数组
即
q z h [ 1 ] = m [ 1 ] qzh[1]=m[1] qzh[1]=m[1]
q z h [ 2 ] = m [ 1 ] + m [ 2 ] qzh[2]=m[1]+m[2] qzh[2]=m[1]+m[2]
… \dots …
q z h [ n ] = m [ 1 ] + m [ 2 ] + m [ 3 ] + ⋯ + m [ n ] qzh[n]=m[1]+m[2]+m[3]+\dots +m[n] qzh[n]=m[1]+m[2]+m[3]+⋯+m[n]
将奶牛同时视为阶段和分类讨论的对象
定义
d
p
dp
dp 数组,令
d
p
[
i
]
dp[i]
dp[i] 代表前
i
i
i 只奶牛过河所花的最少时间
易得状态转移方程
d p [ j ] = m i n ( d p [ j ] , d p [ j − i ] + q z h [ i ] ) dp[j]=min(dp[j],dp[j-i]+qzh[i]) dp[j]=min(dp[j],dp[j−i]+qzh[i])
其中 i i i 代表阶段, j j j代表状态
q z h [ i ] qzh[i] qzh[i] 为带 i i i 头奶牛过河多花的时间
细节见代码注释
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,W,m[2510],qzh[2510],dp[2500010],M;
signed main(){
scanf("%lld%lld",&n,&M);
for(int i=1;i<=n;i++)scanf("%lld",&m[i]),qzh[i]=qzh[i-1]+m[i];//前缀和处理
for(int i=1;i<=n;i++)qzh[i]+=2*M;//前缀和数组元素,加上船上只有FJ时一来一回的时间(2M)
memset(dp,127,sizeof dp);//标准初始化
dp[0]=0;//标准初始化
for(int i=1;i<=n;i++)//枚举阶段
for(int j=i;j<=n;j++)//枚举状态
dp[j]=min(dp[j],dp[j-i]+qzh[i]);//状态转移方程
printf("%lld",dp[n]-M);//输出时要减去一个M,因为dp[n]代表FJ已经将所有奶牛送到了对岸,不用再次返回了
return 0;
}