zoukankan      html  css  js  c++  java
  • poj3404

    题意:一个船能乘2人,船的运行速度为2人中较慢一人的速度,问把n个人运到对岸,最少需要多久。

    分析:我们设最快的为a,次快的为b,最慢的为z,次慢的为y。

    我们先考虑如何将y,z运到对岸,可以ab,a,yz,b(yz一起运),也可以ay,a,az,a(yz分开运)。

    我们这两种情况都是只考虑y,z,没考虑x的,那如果y需要和x一起运怎么办呢(x是第三慢的人)

    一起运yz时间:b+a+z+b,分开运时间:y+a+z+a

    比较二者大小只需比较2*b和y+a的大小。

    我们假设单运较快则2*b>y+a,

    y>x  =>  y+a>x+a  =>  2*b>y+a>x+a  =>  2*b>x+a

    通过不等式可以证明如果单运y,z比一起运快,那么yx一起运绝对比单运y,x慢,所以y和x不可能一起运。

    那么有没有可能z需要和x一起呢,也是不可能的。

    运送z不可能影响此4人之外的人。

    一起运,相当于让某人借助z的速度慢得特点,来使得其本身的速度不表现出来(我们注意到一起运的时间时我们并没有用到y的速度。)

    也就相当于z屏蔽了一个人的运行时间,所以一定会选择一个最大的屏蔽,而不会选择较小的。否则那个大的就会被遗留下来,给以后的运送增加负担。

    这样每次运最后两个可以一直让总数减少直到3个以内,直接处理即可

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define maxn 1006
    int n, f[maxn];
    int cal(int a, int b, int y, int z)
    {
    return min(z + a + y + a, b + a + z + b);
    }
    void work()
    {
    int i = n - 1;
    int ans = 0;
    while (i > 2)
    {
    ans += cal(f[0], f[1], f[i - 1], f[i]);
    i -= 2;
    }
    if (i == 2)
    ans += f[0] + f[1] + f[2];
    else
    ans += f[1];
    printf("%d\n", ans);
    }
    int main()
    {
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    scanf("%d", &f[i]);
    sort(f, f + n);
    if (n == 1)
    {
    printf("%d\n", f[0]);
    return 0;
    }
    work();
    return 0;
    }

  • 相关阅读:
    java之Arrays.asList
    MySql索引
    Maven私服搭建
    基于Docker的GitLab搭建
    ubuntu新建组合用户命令不管用
    Linux 安装jdk
    消息队列
    Netty之大动脉Pipeline
    Netty之大名鼎鼎的EventLoop
    Netty之揭开BootStrap 的神秘面纱
  • 原文地址:https://www.cnblogs.com/rainydays/p/2206491.html
Copyright © 2011-2022 走看看