过河
作者:互联网
思路:线性动态规划(这题的状态转移很有特点)
我们先将所有人按花费时间递增进行排序,假设前 ii 个人过河花费的最少时间为 opt[i]opt[i],那么考虑前 i-1i−1 个人已经过河的情况,
即河这边还有 11 个人,河那边有 i-1i−1 个人,并且这时候手电筒肯定在对岸,所以 opt[i] = opt[i-1] + a[1] + a[i]opt[i]=opt[i−1]+a[1]+a[i]
(让花费时间最少的人把手电筒送过来,然后和第 ii 个人一起过河) 。如果河这边还有两个人,一个是第 ii 号,另外一个无关,河那边有 i-2i−2 个人,并且手电筒肯定在对岸,所以
opt[i] = opt[i-2]opt[i]=opt[i−2] ++ a[1] + a[i] + 2* a[2]a[1]+a[i]+2*a[2](让花费时间最少的人把电筒送过来,然后第 ii 个人和另外一个人一起过河,
由于花费时间最少的人在这边,所以下一次送手电筒过来的一定是花费次少的,送过来后花费最少的和花费次少的一起过河,解决问题),
所以opt[i]=min(opt[i−1]+a[1]+a[i],opt[i−2]+a[1]+a[i]+2×a[2])
#include <iostream> #include <cstring> #include <algorithm> using namespace std ; const int N = 1010 ; int a[N] ; int f[N] ; int n ; int main(){ cin >> n ; for(int i=0;i<n;i++){ cin >> a[i] ; } sort(a,a+n) ; for(int i=0;i<n;i++){ if(i == 0){ f[i] = a[i] ; }else if(i == 1){ f[i] = max(a[i],a[i-1]) ; }else{ f[i] = min(f[i-1]+a[0]+a[i],f[i-2]+a[i]+2*a[1]+a[0]) ; } } cout << f[n-1] << endl ; return 0 ; }
标签:opt,过河,int,ii,花费,最少 来源: https://www.cnblogs.com/gulangyuzzz/p/12482613.html