zoukankan      html  css  js  c++  java
  • P3842 [TJOI2007]线段

    题目描述

    在一个 n*n 的平面上,在每一行中有一条线段,第 i 行的线段的左端点是(i, L(i)),右端点是(i, R(i)),其中 1 ≤ L(i) ≤ R(i) ≤ n。

    你从(1, 1)点出发,要求沿途走过所有的线段,最终到达(n, n)点,且所走的路程长度要尽量短。

    更具体一些说,你在任何时候只能选择向下走一步(行数增加 1)、向左走一步(列数减少 1)或是向右走一步(列数增加 1)。当然,由于你不能向上行走,因此在从任何一行向下走到另一行的时候,你必须保证已经走完本行的那条线段。

    输入格式
    输入文件的第一行有一个整数 n,以下 n 行,在第 i 行(总第(i+1)行)的两个整数表示
    L(i)和 R(i)。

    输出格式
    输出文件仅包含一个整数,你选择的最短路程的长度。 题目链接

    状态表示:f[i][0] 表示走完前i行并且最终停到左端点的路程长度,f[i][1]表示停到右端点
    状态计算:
    f[i][0] = min(f[i-1][0] + dist(l[i-1],r[i]) + dist(r[i],l[i]) + 1, f[i-1][1] + dist(r[i-1],r[i]) + dist(r[i],l[i]) + 1);
    f[i][1] = min(f[i-1][0] + dist(l[i-1],l[i]) + dist(l[i],r[i]) + 1, f[i-1][1] + dist(r[i-1],l[i]) + dist(l[i],r[i]) + 1);

    代码:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 20010;
    
    int n;
    int l[N],r[N];
    int f[N][2];
    
    int main()
    {
        cin >> n;
        for(int i = 1;i <= n;i++) cin >> l[i] >> r[i];
        
        f[1][0] = r[1] - 1 + r[1] - l[1];
        f[1][1] = r[1] - 1;
        for(int i = 2;i <= n;i++)
        {
            f[i][0] = min(f[i-1][0] + abs(l[i-1]-r[i]) + r[i] - l[i], 
                          f[i-1][1] + abs(r[i-1]-r[i]) + r[i] - l[i]) + 1;
            f[i][1] = min(f[i-1][0] + abs(l[i-1]-l[i]) + r[i] - l[i],
                          f[i-1][1] + abs(r[i-1]-l[i]) + r[i] - l[i]) + 1;
        }
        cout << min(f[n][0] + n - l[n],f[n][1] + n - r[n]) << endl;
        return 0;
    }
    
  • 相关阅读:
    mkfs
    Nginx配置指令location匹配符优先级和安全问题
    Nginx 403 Forbidden
    nginx 开机启动脚本 可以使用systemctl enable service 添加开机启动
    systemctl
    Pycharm 项目设置Github账户
    sql存储过程
    vim 替换模式
    python--爬虫小案例
    python--正则表达式
  • 原文地址:https://www.cnblogs.com/zcxy/p/12908610.html
Copyright © 2011-2022 走看看