[2020年牛客算法入门课练习赛2] 迁徙过程中的河流

迁徙过程中的河流

题解:
经典dp题,那么状态如何表示,状态如何转移?
很容易想到dp[i]:前i个人全部过河需要的时长。
那么状态如何转移?
将过河时间从小到大进行排序

  1. 其实样例中已经给了一种转移方法,由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]
  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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44235989/article/details/106821001