首页 > 其他 > 详细

POJ 1700 & NYLG 47 过河问题(贪心 || DP)

时间:2014-04-07 21:08:29      阅读:537      评论:0      收藏:0      [点我收藏+]

链接 :http://poj.org/problem?id=1700

http://acm.nyist.net/JudgeOnline/problem.php?pid=47

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

思路分析 :

当n=1,2,3时所需要的最小时间很容易求得,现在由n>=4,假设n个人单独过河所需要的时间存储在数组t中,将数组t按升序排序,即数组中所表示的时间是递增的.
那么这时将单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:

    1> 最快的(即所用时间t[0])和次快的过河,然后最快的回来,再次慢的和最慢的过河,然后次快的回来.

    2> 最快的和最慢的过河,然后最快的回来,再最快的和次慢的过河,然后最快的回来.

    这样就将过河所需时间最大的两个人送过了河,而对于剩下的人,采用同样的处理方式,接下来做的就是判断怎样用的时间最少.
    1> 方案1所需时间为:t[0]+2*t[1]+t[n-1];

    2> 方案2所需时间为:2*t[0]+t[n-2]+t[n-1];

    如果方式1优于方式2,那么有:t[0]+2*t[1]+t[n-1]<2*t[0]+t[n-2]+t[n-1] 化简得:2*t[1]<t[0]+t[n-2]
    即此时只需比较2*t[1]与t[0]+t[n-2]的大小关系即可确定最小时间,此时已经将单独过河所需时间最多的两个人送过了河,那么剩下过河的人数为:n-=2,采取同样的处理方式.

(注意:此题的贪心策略是动态的!!!)


代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAXN 1000         //最多人数
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

int s[MAXN];

int cmp(const void *a, const void*b) //按时间从小到大排序
{
    return *(int *)a - *(int *)b;
}

int main()
{
    int cas, n, k, st, a, b;
    scanf("%d", &cas);
    while(cas--) {
        scanf("%d", &n);
        for(int i=0; i<n; ++i) {
            scanf("%d", &s[i]);
        }
        qsort(s, n, sizeof(int), cmp);
        if(n == 1 || n == 2) {
            printf("%d\n", s[n-1]);
            continue;
        }
        st = 0;
        if(n % 2) {            //最后一次过河所需的时间,分为奇数和偶数两种情况
            st+= s[0] + s[1] + s[2];
        }else {
            st+= s[1];
        }
        k = (n - 2) / 2;                       //贪心的次数
        for(int i=0; i<k; ++i) {                  //贪心的策略
            a= s[0] + 2 * s[1] + s[n-1];
            b= 2 * s[0] + s[n-1] + s[n-2];
            if(a < b) {
                st += a;
            }else {
                st += b;
            }
            n -= 2;
        }
        printf("%d\n", st);
    }
    return 0;
}


POJ 1700 & NYLG 47 过河问题(贪心 || DP),布布扣,bubuko.com

POJ 1700 & NYLG 47 过河问题(贪心 || DP)

原文:http://blog.csdn.net/keshacookie/article/details/23116935

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!