zoukankan      html  css  js  c++  java
  • 过河到对面(动态规划)

    题目:一天晚上,有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 }
  • 相关阅读:
    Java基础语法(11)-面向对象之关键字
    Java基础语法(10)-面向对象之三大特征
    Java基础语法(9)-面向对象之类的成员
    Java基础语法(8)-数组中的常见排序算法
    Java基础语法(7)-数组
    Java基础语法(6)-注释
    Java基础语法(5)-特殊流程控制语句
    Java基础语法(4)-流程控制
    Java基础语法(3)-运算符
    sunset: dawn
  • 原文地址:https://www.cnblogs.com/mld-code-life/p/12270297.html
Copyright © 2011-2022 走看看