先看题目: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]);
}