| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 582 人关注过本帖
标题:过河问题,新人求解
只看楼主 加入收藏
wang20142052
Rank: 1
等 级:新手上路
帖 子:10
专家分:6
注 册:2015-9-8
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:2 
过河问题,新人求解
N个人,只有一条船,每个人都有一个划船速度,要求让N个人过河,一次渡河包括两个人先过去,一个人再回来。每次时间取两个人之间用时最多的,一个人的时候的时间就是他自己所用的。求让N个人过完河所用的最短时间。
先把每个人的所需时间从小到大排序,先考虑简单的情况,一个人,自己过去就可以了。两个人,取时间最长的那个,三个人,最优的是三个人所用时间之和(每让最快的那个单独划船回来)。
四个人或四个以上,就要考虑不同的决策把最慢和次慢的人渡河。有两种决策。
1.始终让最快的单独划船。  最快的和最慢的一起渡河,然后最快的划回来,最快和次慢的一起渡河,最快的再回来。
2.让最快和次快的先过河,最快的划回来,接着最慢和次慢的过河,让次快的划回来。
两种决策中取时间最短的。
Sample Input
4
1 2 5 10
Sample Output
17
这是我的代码,总有两个测试用例过不去,求大神指点
#include <stdio.h>
#include <math.h>
int main()
{
    int a[100000];
    int i,j,t,N,m,n,t1,t2,k;
    scanf ("%d",&N);
    for (i=0;i<N;i++)
    scanf ("%d",&a[i]);
    for (i=0;i<N;i++)
       for (j=0;j<N-i-1;j++)
       {
             if (a[j]>a[j+1])
             {
                 t=a[j];
                 a[j]=a[j+1];
                 a[j+1]=t;
             }
       }
     if (N>=4)
     {
         m=0;
        n=0;
        k=N%2;
        for (j=0;j<(N/2);){
         n=a[0]+a[1]+a[N-1-j]+a[1]+n;
         j=j+2;}
        if (k==0)  t2=n+a[1];
        else  t2=n+a[0]+a[1]+a[2];
         for (i=0;i<=(N/2);i++)
          m=a[0]+a[N-i-1]+m;
        if (k==0)  t1=m-a[0];
        else  t1=m+a[1];
        if (t1>t2)
        printf ("%d\n",t2);
        else
        printf ("%d\n",t1);
     }      
     else
     {
         if (N==1)
         printf ("%d\n",a[0]);
         if (N==2)
         printf ("%d\n",a[1]);
         if (N==3)
         printf ("%d\n",a[0]+a[1]+a[2]);
     }
}
2015-09-15 18:14
lowrie
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:81
专家分:138
注 册:2015-3-12
收藏
得分:20 
这是我的代码,不排除有错,还有就是一人,两人,三人者三种情况我没判断,简单说下我的逻辑,对于策略1很简单,不说了。
假设数组a[0];a[1];a[2]....a[n-1]代表n人按升序排列
看策略二,我是这么理解,先把最小的两个送过去,用时a[1],这看着初始情况。
然后a[0]回来,a[n-1]和a[n-2]过河,a[1]回来,a[0]和a[1]过河,又回到了初始情况。只不过a[n-1]和a[n-2]已经过河,反复这个步骤,直到最后岸边只剩一个人或两个人,两个人时一样,一个人时,a[0]和剩余的一个人直接过了。


#include <stdlib.h>
#include <stdio.h>

int main(){
    int n,i,h,current,sum;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    sum=a[1];
    current=n-1;//当前岸边时耗最长的人
    while(current>=2){//循环条件,岸边剩余的人不可能比a[2]还小。
        if(current==2){//岸边最后只剩一个时的特殊情况
            sum+=a[0]+a[2];
            break;
        }else{
            sum+=a[0]+a[current]+a[1]+a[1];
            current=current-2;
        }
    }
    h=0;
    for(i=1;i<n;i++)
        h+=a[i];
    h+=a[0]*(n-2);

    printf("h==%d\n",h);//策略1最后消耗的时间
    printf("sum==%d\n",sum);//策略二最后消耗的时间
    system("pause");
    return 1;
}
2015-09-17 13:54
wang20142052
Rank: 1
等 级:新手上路
帖 子:10
专家分:6
注 册:2015-9-8
收藏
得分:0 
回复 2楼 lowrie
多谢指点

黑白线
2015-09-18 18:42
快速回复:过河问题,新人求解
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026858 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved