zoukankan      html  css  js  c++  java
  • 过桥

    过桥

    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
  • 相关阅读:
    mysql常用基本命令
    mysql8.0.13下载与安装图文教程
    k8s ingress 增加跨域配置
    Jenkins 备份恢复插件 thinBackup 使用
    k8s HA master 节点宕机修复
    nginx 跨域问题解决
    mongodb 3.4.24 主从复制
    k8s 线上安装 jenkins并结合 jenkinsfile 实现 helm 自动化部署
    k8s helm 运用与自建helm仓库chartmuseum
    centos6 源码安装 unzip
  • 原文地址:https://www.cnblogs.com/gznb/p/11210674.html
Copyright © 2011-2022 走看看