先看题目:https://ac.nowcoder.com/acm/contest/5968/C
题目描述:
n个人通过小船渡河,小船每次只能运两人,渡河时间等于两人渡河最慢的那个的时间,(小船要考虑有人划回来),问最少花费多长时间能够把n个人送到对岸?
解题思路:
先考虑范围小一点的时候,n==1,n==2都很显然,n==3也比较显然,1当渡夫,把2,3挨个送到对岸,当n==4的时候就有点麻烦了,n==4时,可以1当渡夫把2,3,4挨个接过去,这样的话时间是:t[2]+t[1]+t[3]+t[1]+t[4], 然而还有一种方法,也有可能成为答案,思想就是尝试把t[3]弄掉,可以让1,2先划过去,然后1划回来,让3,4划过去,2划回来,1,2再划过去。这样的话时间是:t[2]+t[1]+t[4]+t[2]+t[2],最后答案就是min{2t[1]+t[2]+t[3]+t[4], t[1]+3t[2]+t[4]}
用f[i]表示前i个人渡河所花的最短时间,f[i]=min{f[i-1]+t[1]+t[i], f[i-2]+t[1]+t[i]+2t[2]}
听完这题的讲解,又一遍刷新了我对dp的理解...
*代码:**
#include<bits/stdc++.h> using namespace std; const int M = 1e5+7; int t[M]; int dp[M]; int main() { int n; scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%d",&t[i]); } sort(t+1, t+n+1); dp[1] = t[1]; dp[2] = t[2]; for(int i = 3; i <= n; i++) { dp[i] = min(dp[i-1]+t[1]+t[i], dp[i-2]+t[1]+t[i]+2*t[2]); } printf("%d\n",dp[n]); }