• Sicily 1264. Atomic Car Race 解题报告(动态规划)


    题目传送门:1264. Atomic Car Race

     

     思路:

      如图,输入a1,a2,...an,图中共有n + 1个点,现在将这些点依次标记为0,1,2...n,现在要求找出由0到n的最短时间。

      很容易发现求解这个问题的过程包含求解最优子结构的过程而且子问题是有重叠的,所以使用动态规划的方法。这里用s[n + 1][n + 1]来记录2个点之间的最短时间,任意 0 <= i <= j <= n , s[i][j]记录的是从i点到j点的最短时间,这样s[0][n]就是问题的解。

      为了构建s,首先要构建一个辅助数组t[n + 1],t[k](0 <= k <= n) 表示由刚换完轮胎开始,连续不换胎行驶k公里的路程需要的时间。由于t[k]可以利用t[k - 1]的值和题目给出公式算出,所以构建t数组需要时间O(n).

      下面用自底向上的方法构建s。要计算s[i][j],假设在i,j之间的某点k进行换胎可得最优解,有s[i][j] = s[i][k] + s[k][j] + b.为了找出k点可以遍历一次i到j之间的所有点都计算一次即可。当然s[i][j]也可能等于t[a[j] - a[i]](不用换胎的情况)。有了递推公式,现在要验证在计算s[i][j]时所有有关的子问题都已经算出。假设i到j的长度为l,由于k在i,j之间,显然i到k的长度和k到j的长度都小于l,这样只要随l由小到大的构建s即可。

      注意最后输出要用fixed保持足够精度,一开始没有使用结果WA.

    代码:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int main(){
     5     int n;
     6     while(cin >> n && n != 0){
     7         int a[n + 1];
     8         a[0] = 0;
     9         for(int i = 1;i <= n;i++)
    10             cin >> a[i];
    11         int r;
    12         double b,v,e,f;
    13         cin >> b >> r >> v >> e >> f;
    14         double t[a[n] + 1]; //t[k] is the total time the car moves k kilometers without changing tires.
    15         t[0] = 0;
    16         for(int i = 1;i <= a[n];i++){
    17             if(i - 1 < r)
    18                 t[i] = t[i - 1] + 1 / (v - f * (r - (i - 1)));
    19             else
    20                 t[i] = t[i - 1] + 1 / (v - e * ((i - 1) - r));
    21         }
    22         double s[n + 1][n + 1]; //s[i][j] is the shortest time move from point ai to aj.
    23         //calculate s in button-up method.
    24         for(int i = 0;i < n + 1;i++)
    25             s[i][i] = 0;
    26         for(int l = 1;l <= n;l++){//length from 1 to n.
    27             for(int i = 0;i <= n - l;i++){
    28                 int j = i + l;
    29                 double min = t[a[j] - a[i]];
    30                 for(int k = i + 1;k < j;k++){
    31                     if(b + s[i][k] + s[k][j] < min){
    32                         min = b + s[i][k] + s[k][j];
    33                     }
    34                 }
    35                 s[i][j] = min;
    36             }
    37         }
    38         cout << fixed << s[0][n] << endl;
    39     }
    40     return 0;
    4
  • 相关阅读:
    记录-java(jxl) Excel导入数据库
    记录--Gson、json转实体类、类转json
    记录--java获取网络资源(图片、音频等)保存本地
    记录--指定路径复制文件到另一个路径
    记录-java执行请求的URL
    记录-Hibernate+servlet实现简单的增、删、查、改
    我的学习之路_第二十八章_JQuery 和validator插件
    我的学习之路_第二十七章_jQuery
    我的学习之路_第二十六章_javaScript(2)
    我的学习之路_第二十五_javaScript
  • 原文地址:https://www.cnblogs.com/jolin123/p/3467135.html
Copyright © 2020-2023  润新知