zoukankan      html  css  js  c++  java
  • 【BZOJ 2072】【POI2004】MOS

    问题描述

    一个夜晚一些旅行者想要过桥. 他们只有一个火把. 火把的亮光最多允许两个旅行者同时过桥. 没有火把或者多于2个人则不能过桥.每个旅行者过桥都需要特定的时间, 两个旅行者同时过桥时时间应该算较慢的那个. 我们想知道所有旅行者最少要花费多少时间才能全部过桥? Example 假如有4个人. 他们分别需要花费6,7,10,15分钟过桥.下图演示了他们如何使用44分钟全部过桥的,但他们能做得更快么?

    输入格式

    第一行一个数n 表示旅行者的总数, 1 ≤ n ≤ 100,000. 接下来n 行表示所有旅行者的过桥时间,时间从小到大排列,每个数不超过1,000,000,000.

    输出格式

    输出一个数表示最少过桥时间.

    样例输入

    4

    6

    7

    10

    15

    样例输出

    42

    题解

    算了十几分钟的样例。。。|ू・ω・` )

    样例算出来就发现,一个人过桥了,除非要给别人送火把,否则显然不会再回来。走得慢的人过桥的次数越少越好,走得快的人只能委屈一下多走几次给别人送火把。于是最优决策有两种,一种是走最快的人和走最慢的人过桥,走最慢的人留在对面,走最快的人把火把送回来;另一种是走最快的人和走次快的人过去,最快的人留在对面,走次快的人把火把送回来,然后走最慢的两个人过去。

    设f[i]表示剩下i个人没过桥所需的最少时间,a[i]表示第i个人过桥需要的时间

    f[i][j]=min(f[i+1]+a[i+1]+a[1], f[i+2]+a[2]*2+a[1]+a[i+2])

     1 #include <cstdio>
     2 #define ll long long
     3 int n,a[100005];
     4 ll f[100005];
     5 ll min(ll x,ll y)
     6 {
     7     return x<y?x:y;
     8 }
     9 int main()
    10 {
    11     int i,j;
    12     scanf("%d",&n);
    13     for (i=1;i<=n;i++) scanf("%d",&a[i]);
    14     if (n==1)
    15     {
    16         printf("%d",a[i]);
    17         return 0;
    18     }
    19     for (i=n-1;i>=2;i--)
    20     {
    21         f[i]=f[i+1]+a[i+1]+a[1];
    22         if (i<=n-2) f[i]=min(f[i],f[i+2]+a[2]*2+a[1]+a[i+2]);
    23     }
    24     printf("%lld",f[2]+a[2]);
    25     return 0;
    26 }
  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/9881620.html
Copyright © 2011-2022 走看看