ACM学习历程——POJ 1700 Crossing River(贪心)

Description

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won‘t be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17

这个题目第一反应是船回的时候,肯定让当前最快的人划回来,然后还考虑到,去的时候是按照最小速度的人,故让最慢的两个人过去,可能会减少时间。于是,考虑两种贪心策略:1、让最快的人来回载人过去。2、先让最快的人和次快的人过去,然后让最快的人回来,让最慢和次慢的人过去,让对面最快的人回来。整体效果是最快和次快的人让最慢和次慢的人过去。于是两者统一,就是让最慢和次慢的人每次渡河。比较两种策略的时间。直到剩余两个或者三个人,就稍微考虑一下即可。另外不要忘了考虑初始只有一个人的情况。

代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <string>
#define inf 0x3fffffff
#define eps 1e-10

using namespace std;

int n, a[1005];

bool cmp(int x, int y)
{
    return x > y;
}

void Input()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);
    sort(a, a+n, cmp);
}

int qt()
{
    if (n == 1 || n == 2)
        return a[0];
    int ans = 0;
    int top = 0, rear = n;
    while (rear - top > 3)
    {
        ans += min(a[rear-2]*2+a[rear-1]+a[top], a[top]+a[top+1]+2*a[rear-1]);
        top += 2;
    }
    if (rear - top == 2)
        ans += a[rear-2];
    else
        ans += a[top] + a[rear-1] + a[rear-2];
    return ans;
}

int main()
{
    //freopen("test.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    for (int times = 0; times < T; ++times)
    {
        Input();
        printf("%d\n", qt());
    }
    return 0;
}
时间: 2024-10-12 21:06:14

ACM学习历程——POJ 1700 Crossing River(贪心)的相关文章

poj 1700 Crossing River(贪心)

分析:题意 源岸数量<=3  很好判断 3:num[0]+num[1]+num[2] 2:num[1] ,1:num[0] 源岸数量>3 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int main(void) { int n,t ; int i,j; int num[1001]; cin>>

POJ 1700 Crossing River(贪心)

V - Crossing River Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1700 Description A group of N people wishes to go across a river with only one boat, which can at most carry two persons. There

[ACM] poj 1700 Crossing River (经典过河问题)

Crossing River Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10212   Accepted: 3855 Description A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arr

poj 1700 Crossing River

Crossing River Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12585   Accepted: 4787 Description A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arr

ACM学习历程—POJ 3764 The xor-longest Path(xor &amp;&amp; 字典树 &amp;&amp; 贪心)

题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor(0, u)^xor(0, v). 所以如果预处理出0结点到所有结点的xor路径和,问题就转换成了求n个数中取出两个数,使得xor最大. 这个之前用字典树处理过类似问题. 代码: #include <iostream> #include <cstdio> #include <cst

ACM学习历程——POJ 2376 Cleaning Shifts(贪心)

Description Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores around the barn. He always wants to have one cow working on cleaning things up and has divided the day into T shifts (1 <= T <= 1,000,000), t

poj 1700 Crossing River C++/Java

http://poj.org/problem?id=1700 题目大意: 有n个人要过坐船过河,每一个人划船有个时间a[i],每次最多两个人坐一条船过河.且过河时间为两个人中速度慢的,求n个人过河的最短时间. 思路: 贪心. 对于每次过河的,有两种情况: //最快和最慢过去,然后最快回来.在和次慢过去.最快回来 int action1=a[i-1] + a[0] + a[i-2] +a[0]; //最快和次慢过去,然后最快回来,在次慢和最慢过去,次慢回来 int action2=a[1] +a[

ACM学习历程——NOJ1113 Game I(贪心 || 线段树)

Description 尼克发明了这样一个游戏:在一个坐标轴上,有一些圆,这些圆的圆心都在x轴上,现在给定一个x轴上的点,保证该点没有在这些圆内(以及圆上),尼克可以以这个点为圆心做任意大小的圆,他想知道自己做多可以与多少个给定的圆相交(相切也算,包含不算). Input 输入有多组数据 输入到文件尾 每一组数据有一个整数n(1<=n<=100000),表示总共有n个圆. 接下是n行,每行两个整数xi,ri表示该圆的圆心坐标和半径. 接下来一行为一个整数x,表示尼克选取点的位置. x xi的范

ACM学习历程—HDU 4726 Kia&#39;s Calculation( 贪心&amp;&amp;计数排序)

DescriptionDoctor Ghee is teaching Kia how to calculate the sum of two integers. But Kia is so careless and alway forget to carry a number when the sum of two digits exceeds 9. For example, when she calculates 4567+5789, she will get 9246, and for 12