計蒜客 藍橋杯模擬 快速過河---dp

計蒜客 藍橋杯模擬 快速過河—dp

題目描述:

在一個夜黑風高的晚上,有 nn 個小朋友在橋的這邊,現在他們需要過橋,但是由於橋很窄,每次只允許不超過兩人通過,他們只有一個手電筒,所以每次過橋後,需要有人把手電筒帶回來,第 ii 號小朋友過橋的時間爲 a_iai​,兩個人過橋的總時間爲二者中時間長者。問所有小朋友過橋的總時間最短是多少。
輸入格式
第一行輸入一個整數 nn,表示有 nn 個小朋友。
第二行有 nn 個整數 a_iai​ ,a_iai​ 表示第 ii 個小朋友過河需要的時間。
輸出格式
輸出一個整數,表示所有小朋友過河所需要的最短時間。

解題思路:
我們定義dp[i]:代表一共有i個人的話,需要花費的最少時間。
首先給數組升序(其中,a[1]是數組的第一個元素),假設現在一共有i個人,那麼可以分爲兩種情況:
(1)沒有過河的人是第i-1個人,和第i個人兩個人【已經有i-2個人已經過河了】:dp[i]=dp[i-2]+a[1]+a[i]+2*a[2];(在dp[i-2]的基礎之上,加上第一個人回來送手電筒的時間【a[1]】+第i-1和第i個人拿着手電筒過河的時間【a[i]】+第2個人回去送手電筒【a[1]】+第1個人和第2個人一起過河的時間【a[2]】)
(2)沒有過河的人是第i個人【已經有i-1個人已經過河了】:dp[i]=dp[i-1]+a[1]+a[i];(在dp[i-1]的基礎之上,加上第一個人回來送手電筒的時間【a[1]】+第1個人和第i個人一起過河的時間【a[i]】)

AC代碼:

//過河 
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
#define min(a,b) a<b?a:b;
using namespace std;
int a[1010];
int dp[1010]; 
int main()
{
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+n+1);
	//dp[i]:代表一共有i個人的話,需要花費的最少時間
	dp[1]=a[1];
	dp[2]=a[2];
	dp[3]=a[1]+a[2]+a[3];
	for(i=4;i<=n;i++)
	{
		dp[i]=min(dp[i-1]+a[1]+a[i],dp[i-2]+a[1]+a[i]+2*a[2]);
	}
	cout<<dp[n]<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章