poj1700(贪心)

题目:

Crossing River

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 13429 Accepted: 5129
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
Source

POJ Monthly–2004.07.18

输入:
t组数据,每组数据先输入一个n,代表人数,接下来是n个人过河所需要的时间。

题意:
将n个人送过河,小船每次最多能送2个人,且必须有人将船划回来,两个人过河的所需要的时间由时间长的来决定,问将所有人送过河所需的最短时间是多少?

思路:
假设a、b是过河所需时间最少的两个人(a<=b),c、d是过河所需时间最长的两个人(c<=d)。
每次送两个人过河有两种选择方案:
1)先将a、b一起送过河,a回来,c、d过河,b回来,一共花费t[b]+t[a]+t[d]+t[b]
2)先将a、d一起送过河,a回来,a、c过河,a回来,一共花费t[d]+t[a]+t[c]+t[a]

每次需要选择最短时间的方案

这里可以看成是将除a、b以外的所有人送过河。

当人数是偶数(n>=2)时很好进行比较,两种方法都剩下a、b。
当人数为奇数(n>=3)的时候,最后会剩下a、b、x 这3个人(x为所需时间第3短的人)
所以需要根据n进行一些特判

代码:

#include 
#include 
#include 
const int maxn = 1000+10;
int arr[maxn];

using namespace std;

int main(){
    int t, n;
    while(cin>>t){
        for(int i=0; icin>>n;
            memset(arr, 0, sizeof(arr));
            for(int i=0; icin>>arr[i];

            sort(arr, arr+n);

            int cnt = 0; 
            if(n<=0) cout<<0<else if(n==1) cout<0]<else if(n==2) cout<1]<else if(n==3) cout<2]+arr[1]+arr[0]<else{
                int flag = -1;
                //除a、b外有tot个人
                int tot = n-2;
                //j为下标
                int j=n-1;
                while(tot>0&&j-1>=0){
                    int solu1 = arr[1]+arr[0]+arr[j]+arr[1];
                    int solu2 = arr[j]+arr[0]+arr[j-1]+arr[0];
                    //tot等于1即最后剩下3个人
                    if(tot==1){
                        flag = 1;
                        cnt = cnt+arr[2]+arr[1]+arr[0];
                        break;
                    }
                    else{
                        if(solu1else
                            cnt+=solu2;
                    }
                    j-=2;
                    tot-=2;
                }
                //tot等于1的时候已经将奇数的条件特判了,这里flag!=1即最后只剩下a、b这种情况
                if(flag!=1){
                    cnt = cnt+arr[1];
                }
                cout<return 0;
}

你可能感兴趣的:(贪心)