过河问题
时间限制: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. mysql的启动和停止

    1.检查数据库服务器是否开启:任务管理器-->后台进程-->查看mysqld是否存在.存在说明开启了,反之没开启 2.管理员运行cmd,输入重启指令:net start **(**数据库名 ...

  2. PCB SVN 服务端VisualSVN Server与TortoiseSVN

    PCB 工程系统SVN源代码招病毒破坏以后,一周时间都没有源代码同步更新了,今天终于将SVN源代码数据恢复并重建SVN服务器,这里将SVN搭建安装过程整理如下 一.服务端SVN安装 1.下载地址:ht ...

  3. [Swift通天遁地]八、媒体与动画-(10)在项目中播放GIF动画

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. 最全的C/C++入门到进阶的书籍推荐,你需要嘛?

    编程是操作性很强的一门知识,看书少不了,但只有学习和实践相结合才能起到很好的效果,一种学习方法是看视频->看书->研究书中例子->自己做些东西->交流->看书. 研究经典 ...

  5. Android高级开发-布局渲染流程与优化

    CPU(中央处理器)与GPU(图像处理器) 主要是设计目标不同,针对不同的应用场景.多缓存多分支,适用于复杂的逻辑运算,主要负责Measure,Layout,Record,Execute的计算操作. ...

  6. ACM_小G的循环

    小G的循环 Time Limit: 2000/1000ms (Java/Others) Problem Description: 一回生,二回熟,三回就腻,小G用for,while循环用得太多了,累觉 ...

  7. HashMap的尾部遍历问题--Tail Traversing

    在看网上HashMap的resize()设计时,提到尾部遍历.   JDK1.7的HashMap在实现resize()时,新table[]的列表采用LIFO方式,即队头插入.这样做的目的是:避免尾部遍 ...

  8. html中保证中文能够正常显示

    <meta http-equiv="Content-Type" content="text/html"; charset=utf-8"/> ...

  9. html5——web字体

    基本介绍 1.自定义网页特殊字体,无需考虑用户电脑上是否安装了此特殊字体,从此把特殊字体处理成图片的时代便成为了过去. 2.支持程度比较好,甚至IE低版本浏览器也能支持. 3.web字体的大小鉴定是字 ...

  10. 仿win8磁贴界面以及功能

    做移动产品界面占很大的一部分,同时也是决定一款产品好的的重要因素,最近看见有人放win8的界面效果,搜了两款,一款是只是仿界面没有特效,另一款是自定义组件能够实现反转效果,今天分析一下这两类界面. 仿 ...