zoukankan      html  css  js  c++  java
  • NYOJ 47:过河问题(思维)

    47-过河问题

    • 内存限制:64MB 时间限制:1000ms 特判: No
    • 通过数:6 提交数:10 难度:5

    题目描述:

    在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。 

    输入描述:

    第一行是一个整数T(1<=T<=20)表示测试数据的组数
    每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
    每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)

    输出描述:

    输出所有人都过河需要用的最少时间

    样例输入:

    复制

    1
    4
    1 2 5 10

    样例输出:

    17

    思路

    因为每次最多过两个人,而且还必须要有手电筒,所以每次过河,总会有一个人返回来送手电筒

    样例是这样推出来的:

    第一次,让1和2过去,1回来送手电

    第二次,5和10过去,2回来送手电

    第三次,1和2过去

    总时间为:2+1+10+2+2  

    从样例可以看出,并不是每次都让最快的和剩下的最慢的一起过河才是最优解

    所以可以分作两种方案:

    1. 最快的人和次快的人过河,最快的人回去送手电,然后未过河的最慢的人和次慢的人一起过河,然后次快的人回去送手电
    2. 最快的人和最慢的人过河,最快的人回去送手电,最快的人和未过河的人中的最慢的人(即之前的次慢的人)一起过河

    就这样每次运送两个人过河,每次时间取上述方案中的花费时间最小的。直到剩下两个人或者三个人的时候。

    可以发现,上述两种方案不论选哪种,运送完两个人过河后,最快的和次快的总是在一起,没有过河。

    所以如果剩下两个人,那么这两个人过河的时间是最长的时间,即次慢的人过河的时间

    如果剩下三个人,那么一定是最快的,次快的,第三快的。花费的时间是这三个人的时间和

    AC代码

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #define ll long long
    #define ms(a) memset(a,0,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x3f3f3f3f
    const double E=exp(1);
    const int maxn=1e6+10;
    using namespace std;
    int a[maxn];
    int main()
    {
    	ios::sync_with_stdio(false);
    	int n;
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		cin>>n;
    		for(int i=0;i<n;i++)
    			cin>>a[i];
    		sort(a,a+n);
    		int res=0;
    		int t1,t2;
    		if(n==1)
    		{
    			cout<<a[0]<<endl;
    			continue;
    		}
    		else if(n==2)
    		{
    			cout<<a[1]<<endl;
    			continue;
    		}
    		else
    		{
    			while(n!=2&&n!=3)
    			{
    				// 方案一
    				t1=a[0]+a[1]+a[1]+a[n-1];
    				// 方案二
    				t2=a[0]+a[0]+a[n-1]+a[n-2];
    				// 取最小的时间相加
    				res+=min(t1,t2);
    				// 人数减二
    				n-=2;
    			}
    			if(n==2)
    				res+=a[1];
    			if(n==3)
    				res+=a[0]+a[1]+a[2];
    			cout<<res<<endl;
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    c语言 数组合并
    c++ 静态函数
    c++ 多继承 公有,私有,保护
    c++ 多继承 public
    stat用法:获取文件对应权限的数字
    sublime text3 (Mac) 快捷键
    c++ 多继承
    C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
    更换主机后SSH无法登录的问题
    ssh 连接不同无线网且IP以及用户名都相同
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324395.html
Copyright © 2011-2022 走看看