• 过桥


    过桥

    Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
    Total Submission(s) : 2   Accepted Submission(s) : 2

    Font: Times New Roman | Verdana | Georgia

    Font Size: ← →

    Problem Description

    GDOI工作组遇到了一个运输货物的问题,现在有N辆车要顺序通过一个单项的小桥,由于小巧太窄了,不能有两辆车并排通过,所以在桥上不能超车,另外,由于小桥建造的时间已经很久,所以只能承受有限的重量,记为Max(吨),即任意时刻在桥上行驶的车辆的总重量不能超过Max(吨)。所以,车辆在过桥的时候必须要有管理员控制,将这N辆车按初始的顺序分组,每次让一个组过桥,并且只有一个组中所有的车辆全部过桥以后才让下一组车辆上桥,现在,每辆沉的重量和最大的速度是已知的,而每组车的过桥时间有该组中速度最慢的那辆车决定。
    现在请你编一个程序,将这N辆车分组,使得全部车辆通过小桥的时间最短。

    Input

    第1行有3个数,分别为Max(吨),Len(桥的长度,单位:Km)。N(3个数之间用一个或多个空格分开。)接下来有N行。每行两个数,第i行当两个数分别表示第i辆车的重量(吨)和最大速度(Km/h).
    注意:所有的输入都为整数,并且任何一辆车的重量都不会超过Max。

    Output

    只有一行,输出全部车辆通过小桥的最短时间(minute),精确到小数点后一位。

    Sample Input

    100 5 10
    40 25
    50 20
    50 20
    70 10
    12 50
    9 70
    49 30
    38 25
    27 50
    19 70

    Sample Output

    75.0

    解释:

    题目首先说明这n辆车的顺序是不可以被改变的,能被改变的是,n辆车的不同分组。从而得到最短的时间。这是一个动态规划题目。当第1...k辆车以最小的时间通过时,k+1...n 也可以是最小时间通过。m..n辆车可以由两组车队来一次通过,其中[m, k]是最优的,[k+1, n]也是最优的。那么[m, n]也是最优的。

    我看了别人的博客才知道状态转移方程,其实对于动态规划题,我认识状态的描述是比较重要的,知道了状态的含义就可以去思考状态转移方程,从而得到解,但是要怎么去想这个状态含义。我经常想不到。可能是做题少了吧。

    对于这个题目,使用两个状态,第一个 t[i][j]表示,[i,j] 区间内,车辆通过所需要的最大时间。第二个f[i]表示,当第 i 辆车通过时所要的最小时间。那么结果就是f[n]。

    对于第一个t, 那么t[i][i] 就是第 i 辆车自己单个通过的时间,t[i][j] = max(t[j][j], t[i][j-1]). t[j][j]是自己的当前时间,t[i][j-1]就是表示和[i, j-1]区间的车队一起通过。

    if (pre[i] - pre[j-1]  <= 最大承重量) f[i] = min(f[i], f[j-1] +  t[j][i]) .其中 pre[i] 是表示前缀和。第 i 辆车通过时所要的最小时间是,当前车辆和 前 第 j 辆车一起走,是pre[j-1]而不是pre[j] 的原因是,per表示前缀和,第 i 辆车和 第 j 辆车一起走时,如果是pre[j] 那么就没有考虑第 j 辆车的重量了。f[j-1] + t[j][i] 表示也是一样的道理,如果是 f[j] 的话,将会重复计算 第 j 辆车的时间。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int N = 1010;
     6 
     7 unsigned long long int pre_sum[N], v, m, len;
     8 
     9 double t[N][N];
    10 double f[N];
    11 
    12 int main() {
    13   int n;
    14   while (cin >> m >> len >> n) {
    15     pre_sum[0] = 0;
    16     for (int i = 1; i <= n; i++) {
    17       cin >> pre_sum[i] >> v;
    18       pre_sum[i] += pre_sum[i-1];
    19       t[i][i] = double(double(len) / double(v));
    20     } 
    21 
    22     for (int i = 1; i < n; i++) {
    23       for(int j = i + 1; j <= n; j++) {
    24         t[i][j] = max(t[j][j], t[i][j-1]);
    25       } 
    26     }
    27     f[1] = t[1][1];
    28 
    29     for (int i = 2; i <= n; i++) {
    30       f[i] = 1e9;
    31       for (int j = i; j >= 1; j--) {
    32         if (pre_sum[i] - pre_sum[j-1] > m) break;
    33         f[i] = min(f[i], f[j-1] + t[j][i]);
    34       }
    35     }
    36     printf("%.1lf
    ", f[n]*60.00);
    37   }
    38   return 0;
    39 }
    View Code
  • 相关阅读:
    小程序实现无限瀑布流
    Vue H5 项目模板
    Taro使用mobx做国际化小程序
    一次国际化记录以及平铺JSON数据
    Promise(interesting)
    返回状态码
    CSS属性兼容写法
    在DOM加载之前insertScript
    关于吸烟
    前端优化措施
  • 原文地址:https://www.cnblogs.com/gznb/p/11210674.html
Copyright © 2020-2023  润新知