过河问题
时间限制: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. 关于pycharm中pip版本10.0无法使用的解决办法

    背景: 近期在利用 pycharm 安装第三方库时会提示 pip 不是最新版本, 因此对 pip 进行更新,但是生成最新版本之后, pip 中由于缺少 main 函数,导致在 pycharm 中无法自 ...

  2. bzoj1877 晨跑(费用流)

    1877: [SDOI2009]晨跑 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2138  Solved: 1145 Description Elax ...

  3. BZOJ 4310 二分+SA+RMQ

    思路: 首先求出后缀数组和height数组,这样能得到本质不同的子串数目 这里利用:本质不同的子串=∑(Len−SA[i]−height[i])=∑(Len−SA[i]−height[i])利用SA[ ...

  4. 如何卸载系统自带的Microsoft Office

    (1)首先.在C盘删除office文件夹. (2)删除注册表 1)开始菜单-->运行-->regedit进入注册表 (window+r  -->) 2)在注册表里找到HKEY_CUR ...

  5. 巧用Eclipse Java编辑器调试

    在使用Eclipse开发Java Web应用时,使用的编辑器不但能够为开发者提供代码编写.辅助提示和实时编译等常用功能,而且还能够对Java源代码进行快捷修改.重构和语法纠错等高级操作.通过Eclip ...

  6. (转)淘淘商城系列——初始SolrCloud

    http://blog.csdn.net/yerenyuan_pku/article/details/72944611 本文我只是简单介绍一下SolrCloud,如果大家要是感兴趣的话,可以参考Sol ...

  7. Sping装配之——自动装配

    Sping从两个角度来实现自动化装配: 组件扫描(component scaning):spring会自动发现应用上下文中所创建的bean; 自动装配(autowiring):spring自动满足be ...

  8. CSS超链接常见四种状态在控制

    一.首选设置一下以下4种状态常: 1.a:active是超级链接的初始状态 2.a:hover是把鼠标放上去时的状况 3.a:link 是鼠标点击时 4.a:visited是访问过后的情况.

  9. Learning opencv续不足(七)线图像的设计D

    因为线图像startline有了起点和终点,我们就可以用DDA法求出线上所有点,任意斜率直线通过四象限八区域查表法界定.我们只示范一个区域:函数为: public PointF DdaFindPtIm ...

  10. 数组题汇总(python3)

    题目主要来自<剑指offer>和LeetCode,用python3来写的代码. 1.二维数组的查找: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列 ...