过河问题
时间限制:1000 ms  |  内存限制:65535 KB
难度:5
描述
在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。

输入
第一行是一个整数T(1<=T<=20)表示测试数据的组数
每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)
输出
输出所有人都过河需要用的最少时间
样例输入
1
4
1 2 5 10
样例输出
17

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 500

int s[MAX];

int cmp(const void *a,const void *b)
{
    return *(int *)a - *(int *)b;
}
int main()
{
    int N;
    scanf("%d",&N);
    while(N--)
    {
        int i,j,k,m,sum;
        scanf("%d",&m);
        memset(s,0,sizeof(s));
        for(i=1;i<=m;i++)
        scanf("%d",&s[i]);
        qsort(s+1,m,sizeof(s[1]),cmp);
        //for(i=1;i<=m;i++)
        //printf("%d ",s[i]);
        k=m;sum=0;
        while(k>3)
        {
            if((2*s[2]+s[1]+s[k])>(s[k]+s[k-1]+2*s[1]))
            sum+=s[k]+s[k-1]+2*s[1];
            else
            sum+=2*s[2]+s[1]+s[k];
            k-=2;
        }
        if(k<=2)
        sum+=s[k];
        if(k==3)
        sum+=s[1]+s[2]+s[3];
        printf("%d\n",sum);       
    }
    return 0;
}

//一般方法 AC
 
/*
解题思路:
  首先按照过河时间从小到大排序,当n>3时候,就是考虑用最小时间先把用时最长的两个人送过河,
且手电筒仍然留在未过河的这边,剩下的再依次求解。

把当前用时最长的两个人送过河可以考虑两种方案:

方案一:
  1 号和 2 号先过河,然后 1 号回来,n 号和 n-1 号过河,然后 2 号再回来
用时:2*s[2]+s[1]+s[n];
方案二:
  1 号和 n 号先过河,然后 1 号再回来,1 号和 n-1 号再过河,之后 1 号再回来
用时:s[n]+s[n-1]+2*s[1];
所以每次把用时最长的两个人送过河用时应该取上述两种方案中的最小值
当 n<=2时,用时 是 s[n]
当 n==3时, 用时是 s[0]+s[1]+s[2]
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 500

int s[MAX];

int cmp(const void *a,const void *b)
{
    return *(int *)a - *(int *)b;
}
//排序 快排
int mintime(int a,int b)
{
    return a < b ? a : b;
}
//比较大小
int f(int n)
{
    if(n<=2) return s[n];
    else if(n==3) return s[1]+s[2]+s[3];
    else
    return f(n-2)+mintime(s[n]+2*s[2]+s[1],s[n]+s[n-1]+2*s[1]);
}
//递归
int main()
{
    int N;
    scanf("%d",&N);
    while(N--)
    {
        int i,j,k,m,sum;
        scanf("%d",&m);
        memset(s,0,sizeof(s));
        for(i=1;i<=m;i++)
        scanf("%d",&s[i]);
        qsort(s+1,m,sizeof(s[1]),cmp);
        //for(i=1;i<=m;i++)
        //printf("%d ",s[i]);
        /*
        k=m;sum=0;
        while(k>3)
        {
            if((2*s[2]+s[1]+s[k])>(s[k]+s[k-1]+2*s[1]))
            sum+=s[k]+s[k-1]+2*s[1];
            else
            sum+=2*s[2]+s[1]+s[k];
            k-=2;
        }
        if(k<=2)
        sum+=s[k];
        if(k==3)
        sum+=s[1]+s[2]+s[3];
        */
        printf("%d\n",f(m));       
    }
    return 0;
}

//递归 AC
 
/*
解题思路:
  首先按照过河时间从小到大排序,当n>3时候,就是考虑用最小时间先把用时最长的两个人送过河,
且手电筒仍然留在未过河的这边,剩下的再依次求解。

把当前用时最长的两个人送过河可以考虑两种方案:

方案一:
  1 号和 2 号先过河,然后 1 号回来,n 号和 n-1 号过河,然后 2 号再回来
用时:2*s[2]+s[1]+s[n];
方案二:
  1 号和 n 号先过河,然后 1 号再回来,1 号和 n-1 号再过河,之后 1 号再回来
用时:s[n]+s[n-1]+2*s[1];
所以每次把用时最长的两个人送过河用时应该取上述两种方案中的最小值
当 n<=2时,用时 是 s[n]
当 n==3时, 用时是 s[0]+s[1]+s[2]
*/

参考原文:http://www.cnblogs.com/dongsheng/archive/2013/04/23/3038333.html

【ACM】nyoj_47_过桥问题_201308151616的更多相关文章

  1. 牛人的ACM经验 (转)

    一:知识点     数据结构:       1,单,双链表及循环链表       2,树的表示与存储,二叉树(概念,遍历)二叉树的                    应用(二叉排序树,判定树,博弈 ...

  2. ACM算法锦集

    一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈树,解答树等) 3,文件操作(从文本文件中读入数据并输出到文本文 件中 ...

  3. SCNU ACM 2016新生赛决赛 解题报告

    新生初赛题目.解题思路.参考代码一览 A. 拒绝虐狗 Problem Description CZJ 去排队打饭的时候看到前面有几对情侣秀恩爱,作为单身狗的 CZJ 表示很难受. 现在给出一个字符串代 ...

  4. SCNU ACM 2016新生赛初赛 解题报告

    新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ...

  5. acm结束了

    最后一场比赛打完了.之前为了记录一些题目,开了这个博客,现在结束了acm,这个博客之后也不再更新了. 大家继续加油!

  6. 关于ACM的总结

    看了不少大神的退役帖,今天终于要本弱装一波逼祭奠一下我关于ACM的回忆. 从大二上开始接触到大三下结束,接近两年的时间,对于大神们来说两年的确算不上时间,然而对于本弱来说就是大学的一半时光.大一的懵懂 ...

  7. 第一届山东省ACM——Phone Number(java)

    Description We know that if a phone number A is another phone number B’s prefix, B is not able to be ...

  8. 第一届山东省ACM——Balloons(java)

    Description Both Saya and Kudo like balloons. One day, they heard that in the central park, there wi ...

  9. ACM之鸡血篇

    一匹黑马的诞生 故事还要从南京现场赛讲起,话说这次现场赛,各路ACM英雄豪杰齐聚南京,为争取亚洲总舵南京分舵舵主之职位,都使出了看 家本领,其中有最有实力的有京城两大帮清华帮,北大帮,南郡三大派上交派 ...

随机推荐

  1. 一、Linux文件权限与目录配置

    行文结构如下: 用户和用户组 Linux文件权限概念 Linux目录配置 重点回顾 1.用户与用户组 Linux是个多用户.多任务的系统,可能有多人同时使用这台机器进行工作,为了考虑每个人的隐私和工作 ...

  2. Road Construction(无向图的双连通分量)

    http://poj.org/problem?id=3352 题意:给出一个有n个顶点m条边的无向连通图,问至少添加几条边,使删除任意一条边原图仍连通. 思路:一个边双连通图删除任意一条边仍为连通图. ...

  3. akka设计模式系列

    由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...

  4. SpringBoot2.0整合Redission

    Redisson是redis一个很强大的客户端,有兴趣的同学可以看我的下一篇文章,这篇主要讲如何整合,费话不多说,直接上干货(大牛请绕道) 首先创建RedissionConfig文件 import o ...

  5. JavaScript--控制类名(className 属性)

    className 属性设置或返回元素的class 属性. 语法: object.className = classname 作用: 1.获取元素的class 属性 2. 为网页内的某个元素指定一个c ...

  6. Mysql(Innodb)如何避免幻读

    Mysql(Innodb)如何避免幻读 有意思 MySQL InnoDB支持三种行锁定方式: 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. 间隙锁(Gap Lock):锁定 ...

  7. iOS动画——DynamicAnimate

    力学动画 以dynamicAnimate为首的力学动画是苹果在iOS7加入的API,里面包含了很多力学行为,这套API是基于Box2d实现的.其中包含了重力.碰撞.推.甩.和自定义行为. 涉及到的类如 ...

  8. android ormlite 清空表

    delete from TableName; //清空数据 update sqlite_sequence SET seq = where name ='TableName';//自增长ID为0 Sam ...

  9. Less——less基本使用

    基本概况 Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充.Less 可以运行在 Node.浏览器 ...

  10. jQuery——stop

    为什么要停止动画? 对同一个元素,如果拥有一个以上的动画对其加以作用,那么后面的动画会被放入一个动画队列中.动画队列的动画是在其上一个动画完成以后才会执行. 控制两个参数四种情况 1.第一个参数表示后 ...