迁徙过程中的河流
题解:
经典dp题,那么状态如何表示,状态如何转移?
很容易想到dp[i]:前i个人全部过河需要的时长。
那么状态如何转移?
将过河时间从小到大进行排序
- 其实样例中已经给了一种转移方法,由dp[i-2]转移而来,当前(i-2)个人已经全部到河对岸,第1个人将船从河对岸开过来花费a[1],然后第(i-1)个人和 第i个人 一起乘船到河对岸用时a[i],然后第2个人从河对岸把船开回来接第1个人,开过来用时a[2],开过去又花费a[2]。
dp[i]=dp[i-2]+a[1]+a[i]+a[2]+a[2] - 由dp[i-1]转移而来,很显然当前(i-1)人到达河对岸时,由贪心策略,把第一个人派回来接第i个人花费最少,状态转移很容易得到。
dp[i]=dp[i-1]+a[i]+a[1]
易得状态转移
dp[i]=min(dp[i-2]+a[1]+a[i]+a[2]+a[2],dp[i-1]+a[i]+a[1])
int a[maxn];
ll dp[maxn];
int main()
{
int n;
cin >> n;
memset(dp, inf, sizeof(dp));
for(int i=1;i<=n;i++) cin >> a[i];
sort(a,a+n);
dp[1]=a[1];
dp[2]=a[2];
for(int i=3;i<=n;i++)
{
dp[i]=min(dp[i-1]+a[1]+a[i],dp[i-2]+a[1]+a[i]+a[2]+a[2]);
}
cout << dp[n] << endl;
}