ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

过河到对面(动态规划)

2020-02-06 20:53:57  阅读:254  来源: 互联网

标签:过河 int 对面 过桥 时间 完河 动态 dp


题目:一天晚上,有n个人在桥的一边,他们需要过桥,过桥时每次不超过两人,他们只有一个手电筒,每次过桥后,需要有人把手电筒带回来,第i号人过桥的时间为a[i],两个人过桥的总时间为二者中时间长者,问所有人过完桥的总时间最短是多少?

输入格式:第一行输入一个整数n(1<=n<=1000),表示有n个人。

        第二行有n个整数ai, ai表示第i个人的过河所需要的时间(1<=ai<=1000)。

输出格式:输出一个整数,表示所有人过完河所需的时间。

思路:动态规划,设dp[n]表示n个人过完河所需的时间。(有最优子结构)

可以先将数组排序,过河时间最短的人在前面,即a[1].  过河有两种情况分析

1.倒着思考:当n个人过完河,手电筒也跟着过来了。所以当n-1人过完河时,手电筒也是跟着过来了。(花费时间最短时间dp[n-1])

   当桥边只剩一个人时,可以让花费时间最少的那个人a[1]过来送手电筒,人员n和人员1一同过河,花费时间为a[n]; 则dp[n]=dp[n-1]+a[n];

2.当桥边剩两个人时,即n-2人已经过河(时间为dp[n-2]),这样人员1先去送手电(时间a[1]),然后人员n和人员n-1同时过河,(时间为a[n]),然后人员2来送手电(时间为a[2]),然后人员1和人员2过桥(时间为a[2])  dp[n]=dp[n-2]+a[1]+2*a[2]+a[n];

最短时间:dp[n]=min( dp[n-1]+a[n] , dp[n-2]+a[1]+2*a[2]+a[n] );

 1 #include<vector>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int a[10010];
 7 int dp[10010];//dp[n]表示n个孩子过河需要的时间
 8 
 9 int main()
10 {
11     int n;
12     cin>>n;
13     for(int i=1;i<=n;i++){
14         cin>>a[i];
15     }
16     sort(a+1,a+n+1); 
17     dp[1]=a[1];
18     dp[2]=a[2];
19     for(int i=3;i<=n;i++){
20         dp[i]=min(dp[i-1]+a[0]+a[i],dp[i-2]+a[0]+2*a[1]+a[i]);
21     }
22     cout<<dp[n]<<endl;
23     return 0;
24 }

 

标签:过河,int,对面,过桥,时间,完河,动态,dp
来源: https://www.cnblogs.com/mld-code-life/p/12270297.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有