poj 1700 Crossing River

来源:互联网 发布:供水企业安全生产软件 编辑:程序博客网 时间:2024/05/22 00:14
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 10787 Accepted: 4064

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

141 2 5 10

Sample Output

17

原题链接

题目大意

有n个人准备过河,他们只有一只船,这只船每次只能通过坐不超过2人(0,1,2人都可以),每个人都有不同的划船速度;同一组过河的人的速度是由较的速度来确定。你的任务是确定一个策略,最大限度的减少他们过河的时间(是他们最快的过河).

第一行是输入一个整数T(1<=T<=20)代表测试的数据组数.

每一组第一行输入一个数据n(n<=1000),代表过河的人数.下面一行有n个整数分别代表,n个人划船的速度.

我的想法.

现在用C[i]来存放存放第i个人划船速度.cost来存放全部n个人过河所用的时间.(cost初始值为0)

现在为了方便计算讲C[],数组安速度由小到大排序

1.如果只有一个人,

cost=C[1];

2.如果只有两个人

cost=C[2];(因为已经排序C[2]>C[1])

2.如果有三个人

一定会有一个人会划船两次(因为船一次不能白所有的人全部载过河,要载其他的人必须要有人把船划回来)

现在假设

节省时间的方法就是让过河用时间最少的划两次船,

假如有

3

2 3 5

用时间为2,用时间3的一起过河,用时间为2的再回来,用时间为2与用时间为5的在过去,

所用时间为2+3+5=10

因此如果是三个人cost=C[1]+C[2]+C[3];

如果是四个人,注意看这种情况是比较普遍的.

假设用时间分别是a,b,x,y

我们可以枚举所有的情况,

最后会发现在众多情况中解一直时出现在这两种情况之间.

1.a是用时最短的.那麽可以让a分四次讲这四个人带到对岸所用时间为.

b+a+c+a+d,(分别是带b过河,划船回来,带c过河,划船回来,带d过河不用划船会来因为没有人要过来了);

2.现将a和b划船到对岸,然后a回来,然后x,y划船到对岸然后b回来然后ab一起过和,

时间为      b+a+y+b+b

1.考虑了划船快的人划的次数最多,

2.考虑了划的满的人尽量少占用化的快的人的时间.

然后在者两种方案中考虑考虑一种较优的方案.四个人可以用最短的时间过河.

如果同样的是四个人只是讲两个较慢的,送到对岸,剩下的人就可以用两个人的情况判断。

1.cost=x+a+y+a

2.cost=b+a+y+b

然后只剩下a,b

他们划船用时间为b.

根据上述情况我们都可以把超过两个三个人的情况处理为2或者三个人的情况.

如果有n个人n>3,n%2==1,就可已通过有限次数最优的方式,将n-3个人送到对岸此时剩下的三个人按三个人的情况来算(为了方便每伦讲靠近最后的2个人,有第一个,与

第二个,送完之后一二没在没有过河,再用他们松下一波人),最后剩余的是1,2,3号

偶数的话最后剩余1,2号.

然后安三个以内的人方法讲剩余的人送过去.

具体如下:

Source CodeProblem: 1700Memory: 360KTime: 0MSLanguage: GCCResult: Accepted    Source Code    #include <stdio.h>    #include <stdlib.h>    #define maxn 5005    int mycmp(const void * pa,const void * pb){    return *((int *)pa) > *((int *)pb);    }    void print(int C[],int n){    int i;    for(i=1;i<=n;i++){    printf("%d ",C[i]);    }    printf("\n");    }    int main(){    int C[maxn]={0},n,i,m;    scanf("%d",&m);    while(m-- > 0){    scanf("%d",&n);    int cost=0;    for(i=1;i<=n;i++){    scanf("%d",&C[i]);    }    qsort(C+1,n,sizeof(C[0]),mycmp);    while(n>3){    if(C[2]+C[2]<C[1]+C[n-1]){    cost+=(C[2]+C[2]+C[1]+C[n]);    }else{    cost+=(C[1]+C[1]+C[n-1]+C[n]);    }    n-=2;    }    if(n<3) cost+=C[n];    else cost+=C[1]+C[2]+C[3];    printf("%d\n",cost);    }    return 0;    }


0 0
原创粉丝点击