过河问题
时间限制: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. shell脚本-基础

    shell脚本-基础 编程基础 程序是指令+ 数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell 程序提供了编程能力,解释执行. 计算运行二进 ...

  2. jquery得到焦点和失去焦点

    鼠标在搜索框中点击的时候里面的文字就消失了,经常会用到搜索框的获得焦点和失去焦点的事件,接下来介绍一下具体代码,感兴趣的朋友额可以参考下   input失去焦点和获得焦点 鼠标在搜索框中点击的时候里面 ...

  3. Jsoup爬虫获取公司纳税识别号

    天眼查 /** * 根据公司名称获取统一社会信用代码 * * @author xiaofei.xian 日期:2019年3月20日 上午11:12:41 */ public class GetTaxN ...

  4. Win10中的睡眠、休眠

    共同点: 都是节能技术. 异同点: 睡眠: 需要耗电.通过键盘鼠标唤醒.唤醒速度快.将用户正在处理的数据保存到内存中,除内存以外的所有设备都停止供电. 休眠: 不需耗电.通过电源键唤醒.唤醒速度慢.将 ...

  5. Android popwindow 消失监听

    LisviewPop.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { //改变显示 ...

  6. 移动web——bootstrap栅格系统

    基本简介 1.Bootstrap 提供了一套响应式.移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列 2.栅格系统用于通过一系列的行(row)与列(c ...

  7. JS——三元表达式

    三元表达式: var n1 = 2 > 3 ? true : false; alert(n1);//返回false

  8. [Windows Server 2003] 安装网站伪静态

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

  9. 如何在linux搭建airtest+chromeweb测试环境--(用命令行运行.air脚本)

    大前堤: 如果你需要airtest提供的可视化测试报告,那你的操作系统,一定要有图形化界面. 否则运行你的airtest脚本 会遇到这样的问题 Xlib.error.DisplayNameError: ...

  10. mysqlconnector将EXCEL表数据导入数据库

    测试excel和脚本放在同一个目录 测试excel和脚本放在同一个目录 #!/usr/bin/env python #coding=utf-8 import xlrd import mysql.con ...