过河问题
时间限制: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. C#窗体间传值的简便方法/工具

    一.问题:窗体间传值必须需要窗体之间有联系,具体有如下方式 窗体间传值涉及到窗体A必须拥有窗体B,这样才可以实现A-B之间传值 窗体A与窗体B在窗体/实例C中,A-B可互相通讯 其他方式,不细讨论,复 ...

  2. windows2003下svn的安装

    Windows2003下svn平台搭建 编辑:dnawo 日期:2010-08-03 转自http://www.mzwu.com/article.asp?id=2557 字体大小: 小 中 大     ...

  3. 我的周记1——”云想衣裳花想容"

    这里记录过去一周,我学习到的,思考的,看到的,每周五发布. http 网上参考http入门协议  https://juejin.im/post/5afad7f16fb9a07abf72ac30 超文本 ...

  4. .net C# 格式化时间

    1.HtmlEncode="False" 2.DataFormatString="{0:d}" C#格式化日期时间 DateTime dt = DateTime ...

  5. android:scaleType 布局文件加载图片时候的显示方式

    android:scaleType="center" 以原图的几何中心点和ImagView的几何中心点为基准,按图片的原来size居中显示,不缩放,当图片长/宽超过View的长/宽 ...

  6. Redis 的简单运算

    Redis 的简单运算 命令 说明 备注 incr key 在原字段上加 1 只能对整数操作 incrby key increment 在原字段上加上整数 (increment) 只能对整数操作 de ...

  7. [Windows Server 2008] 安装网站伪静态

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装IIS伪静 ...

  8. 3星|《管理十诫》:十年前可口可乐退休CEO的一生管理经验总结

    管理十诫:影响你一生的管理哲学 英文书应该是2008年出版的.国内出版过几个译本. 作者是可口可乐CEO.本书是他从可口可乐CEO退下来后写的管理经验总结.作者总结了11条CEO不应该做的事.这11条 ...

  9. HDU_1542_线段树【扫描线】

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  10. Redis 之消息发布与订阅(publish、subscribe)

    使用办法: 订阅端: Subscribe 频道名称 发布端: publish 频道名称 发布内容 一般做群聊,聊天室,发布公告信息等.