UVA - 10037 Bridge 贪心

题目大意:有n个人要过桥,每次只能过去两个,且这两个人中至少有一个人要带手电筒,但手电筒只有一个。

每个人都有一个过桥时间,两个人的过桥时间取决于时间长的那个。

问所有人都过桥需要多少时间,怎么过桥

解题思路:贪心,因为所有人都要过桥,且手电筒只有一个,所以要过桥时间短的人把手电筒拿回来。

有两种过桥方式使过桥时间达到最短,假设t1,t2(t1 <= t2)是当前过桥时间最短的两个人,tm,tn是过桥时间最长的两个人,且(tm <= tn)

第一种过桥方式:(不考虑最后一次t1和t2一起过桥)

t1和t2先过去,t1把手电筒拿回来,tn和tm过去,t2把手电筒拿回来,这样过桥总时间是t2 + t1 + tn + t2

第二种过桥方式:(也不考虑t最后一次的t1和t2一起过桥)

t1和tn过去,t1回来,t1和tm过去,t1回来,这样过桥总时间为tn + t1 + tm + t1

现在只需要比较哪种过桥时间短就可以了

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 1010
int v[maxn], n;

void init() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &v[i]);
    sort(v + 1, v + n + 1);
}

void cal() {
    int sum = v[2];
    for(int i = n; i > 3; i -= 2)
        sum += min(2 * v[2] + v[1] + v[i],2 * v[1] + v[i] + v[i -1]);
    if(n % 2)
        sum += v[1] + v[3];

    printf("%d\n", sum);
    for(int i = n; i > 3; i -= 2) {
        if(2 * v[2] + v[1] + v[i] < v[i] + 2 * v[1] + v[i - 1])
            printf("%d %d\n%d\n%d %d\n%d\n",v[1],v[2],v[1],v[i-1],v[i],v[2]);
        else
            printf("%d %d\n%d\n%d %d\n%d\n",v[1],v[i],v[1],v[1],v[i-1],v[1]);
    }
    if(n % 2)
        printf("%d %d\n%d\n",v[1],v[3],v[1]);
    printf("%d %d\n",v[1],v[2]);
}

void solve() {
    if(n == 1) {
        printf("%d\n%d\n", v[1], v[1]);
        return ;
    }
    if(n == 2) {
        printf("%d\n%d %d\n",v[2], v[1], v[2]);
        return ;
    }
    cal();
}

int main() {
    int test;
    scanf("%d", &test);
    while(test--) {
        init();
        solve();
        if(test)
            printf("\n");
    }
    return 0;
}
时间: 2024-10-19 08:11:31

UVA - 10037 Bridge 贪心的相关文章

UVA 10037 Bridge (基础DP)

题意: 过河模型:有n个人要渡河,每个人渡河所耗时可能不同,只有1只船且只能2人/船,船速取决于速度慢的人.问最少耗时多少才能都渡完河? 思路: n<2的情况比较简单. 考虑n>2的情况,第一次肯定是两个耗时少的先过去.接下来有两种渡河方式,有可能是{a回,另外2人去,b回,a和b去},也可能是{a回,a和另一人去}.也就是说a和b的协作可以送走其他2个人,或者是a自己当船夫,送走另外一个人.这样子就有两种决策啦. 先将他们排个序(升序),然后a和b先过去.如果还有人没有过河,若left>

UVa 10037 - Bridge

题目大意 在一个晚上有N个人过河,他们有一个手电筒,需要有手电筒才能过河,每次最多两个人同时过河,每次过河时间等于速度最慢的那个人的过河时间,让所有人全部过河,花费的时间最少是多少? 分析 如果只有一个人过河,那么过河的总时间就是这个人过河的时间.如果是两个人过河,那么总时间为过河速度较慢的那个人的过河时间.如果是三个人过河,总花费时间为a+b+c.当人数大于等于4时,我们每次都让两个速度最慢的人过河,假设A和B表示速度最快和第二快的人,速度分别为a,b,C和D表示速度最慢和第二慢的人,速度分别

uva 1356 - Bridge(积分+二分)

题目链接:uva 1356 - Bridge 题目大意:在一座长度为B的桥上建若干个塔,塔的间距不能超过D,塔的高度为H,塔之间的绳索形成全等的抛物线.绳索的总长度为L.问在建最少塔的情况下,绳索的最下段离地面的高度. 解题思路:贪心的思想求出最少情况下建立的塔数. 二分高度,然后用积分求出两塔之间绳索的长度. C++ 积分 #include <cstdio> #include <cstring> #include <cmath> #include <algori

uva 1511 - Soju(贪心)

题目链接:uva 1511 - Soju 题目大意:给出两个点集,问说分别从两个点集中取一点的哈夫曼距离最小值.注意一个点集的x坐标小于0,另一个大于0. 解题思路:因为x2一定大于x1,所以对于x这一维,一定是+x2-x1,所以只需要考虑y这一维坐标即可. #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> u

UVA 1356 - Bridge(自适应辛普森)

UVA 1356 - Bridge 题目链接 题意:一个桥长为B,桥上建电线杆,杆高为H,两杆之间距离不超过D,电线杆总长为L,杆子都是等距的,现在建最少的电线杆,问这时候电线离地面高度是多少 思路:二分高度,求出电线长,判断长度够不够即可,那么问题就变成怎么求弧长 求弧长公式为∫w/201+(f′(x)2)??????????√, 建立坐标系使得f(x)=ax2,带入点(w/2, h)求出a,得到方程 那么问题就变成怎么求这个积分了 利用辛普森自适应法,去求即可 代码: #include <c

UVa 1617 Laptop (贪心)

题意:有n个长度为1的线段,确定它们的起点,使得第i个线段在[ri,di]之间,输出空隙数目的最小值. 析:很明显的贪心题,贪心策略是这样的,先把所有的区间排序,原则是按右端点进行排序,如果相等再按左端点排,然后再扫一遍,如果第一个区间的右端点和第二个右端点一样, 一定可以相邻,如果不相等,再看是不是与左端点大小关系,如果小于左端点,那么就一定会产生空隙,如果不是小于,就可以,那么端点要向右移动一个单位,其他的也样判断. 代码如下: #include <cstdio> #include <

UVA - 1356 Bridge

Description A suspension bridge suspends the roadway from huge main cables, which extend from one end of the bridge to the other. These cables rest on top of high towers and are secured at each end by anchorages. The towers enable the main cables to

UVa 11039 (排序+贪心) Building designing

白书上的例题比较难,认真理解样例代码有助于提高自己 后面的练习题相对简单,独立思考解决问题,增强信心 题意:n个绝对值各不相同的非0整数,选出尽量多的数排成序列,使得该序列正负交错且绝对值递增. 解法:先按绝对值从小到大排序,然后第一个数先入队,然后依次比较后面的数,如果和队尾的数符号相反则入队,直到所有的数遍历完为止 这里用了异或运算,因为这里面没有0,所谓符号相同的两个数异或值为正,不同符号的数异或值为负 1 //#define LOCAL 2 #include <algorithm> 3

uva 1442:Cave(贪心)

题意:一个洞穴长n,告诉你每个位置的地面高度和顶部高度,让你往里灌水,要求水不能碰到天花板(但可以无限接近).求最多的水量.(洞穴两边视为封闭) 思路:如果知道一个位置向左看最高可以多高,向右看最高可以多高,就可以知道这个位置最终的高度了.方法是扫两次.每次扫的时候,定义一个之前最高值.若之前最高值高于现在的顶,则下降至顶.若低于底,则上升至底(因为后面的这种高度能被这个底挡住).如果在中间则不用变. 代码: #include <cstdio> #include <cstring>