因为每行必须走完才能到下一行,所以我们有两种决策:

1、最后留在线段左端点

2、最后留在线段右端点

这种存在状态转移且多决策的问题用动态规划来进行递推是最好不过的了。

所以我们设\(dp[i][0/1]\)来表示在第\(i\)行最后留在左/右端点的行走路径最小值。然后设\(sum[0/1][0/1]\)来表示相邻行左右端点之间的距离。(0表示左端点,1表示右端点)

然后很容易就知道状态转移的式子:

\(dp[i][0]=min(dp[i-1][0]+1+dis[0][0],dp[i-1][1]+1+dis[1][0])\)

\(dp[i][1]=min(dp[i-1][0]+1+dis[0][1],dp[i-1][1]+1+dis[1][1])\)

然后就是注意相邻两行左右端点之间的距离是存在3*2种分类讨论情况的(具体操作见代码)。

我的思路可能有点麻烦了,所以代码写的也有点长,但是自我认为超级暴力超级清楚。。。。。

以下是代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 20010
#define int long long
using namespace std;
int n;
int dp[MAXN][2],dis[2][2],l[MAXN],r[MAXN];
//dis[0][0] left->left
//dis[0][1] left->right
//dis[1][0] right->left
//dis[1][1] right->right
int ans;
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&l[i],&r[i]);
l[0]=r[0]=1;
l[n+1]=r[n+1]=n;
for(int i=1;i<=n+1;i++)
{
if(l[i-1]<l[i])
dis[0][0]=r[i]-l[i-1]+r[i]-l[i],dis[0][1]=r[i]-l[i-1];
else if(l[i-1]>r[i])
dis[0][0]=l[i-1]-l[i],dis[0][1]=r[i]-l[i]+l[i-1]-l[i];
else
dis[0][0]=2*r[i]-l[i-1]-l[i],dis[0][1]=l[i-1]-l[i]+r[i]-l[i];
//the last position of the point is on the left
if(r[i-1]<l[i])
dis[1][0]=r[i]-r[i-1]+r[i]-l[i],dis[1][1]=r[i]-r[i-1];
else if(r[i-1]>r[i])
dis[1][0]=r[i-1]-l[i],dis[1][1]=r[i-1]-l[i]+r[i]-l[i];
else
dis[1][0]=r[i]-r[i-1]+r[i]-l[i],dis[1][1]=r[i-1]-l[i]+r[i]-l[i];
//the last position of the point is on the right
dp[i][0]=min(dp[i-1][0]+1+dis[0][0],dp[i-1][1]+1+dis[1][0]);
dp[i][1]=min(dp[i-1][0]+1+dis[0][1],dp[i-1][1]+1+dis[1][1]);
}
printf("%lld\n",min(dp[n+1][0],dp[n+1][1])-2);
return 0;
}

[TJOI2007] 线段的更多相关文章

  1. luogu [TJOI2007]线段

    题目链接 luogu [TJOI2007]线段 题解 dp[i][0/1]第i行在左/右端点的最短路 瞎转移 代码 #include<bits/stdc++.h> using namesp ...

  2. 【洛谷 P3842】[TJOI2007]线段(DP)

    裸DP.感觉楼下的好复杂,我来补充一个易懂的题解. f[i][0]表示走完第i行且停在第i行的左端点最少用的步数 f[i][1]同理,停在右端点的最少步数. 那么转移就很简单了,走完当前行且停到左端点 ...

  3. P3842 [TJOI2007]线段

    最近多刷些dp,觉得这个算不上蓝题   在一个\(n\times n\)的平面上,在每一行中有一条线段,第\(i\)行的线段的左端点是\((i, L_i)\),右端点是\((i, R_i)\),其中\ ...

  4. [TJOI2007] 线段 (动态规划)

    题目链接 Solution 传统的线性 \(dp\) . \(f[i][0]\),\(f[i][1]\) 分别表示最后一次在 \(i\) ,然后在 左边或者右边的最小步数. 然后就每次根据上一次左边和 ...

  5. DP擎天

    DP! 黄题: 洛谷P2101 命运石之门的选择 假装是DP(分治 + ST表) CF 982C Cut 'em all! 树形贪心 洛谷P1020 导弹拦截 单调队列水题 绿题: 洛谷P1594 护 ...

  6. NOIP前刷题记录

    因为本蒻实在太蒻了...对于即将到来的NOIP2018ssfd,所以下决心要把自己近期做过的题目(衡量标准为洛谷蓝题难度或以上)整理一下,归归类,简单地写一下思路,就当作自己复习了吧qwq 本随笔持续 ...

  7. NOIP刷题

    搜索 [NOIP2013]华容道 最短路+带剪枝的搜索,是一个思维难度比较大的题目. CF1064D Labyrinth 考虑贪心,用双向队列bfs [NOIP2017]宝藏 剪枝搜索出奇迹 题解:h ...

  8. NOIpDairy

    Day 0 水水比赛 Day 1 写写Dp Part1:Dp基础练习 [HNOI2002]公交车路线 秒切,点数这么少,N这么大,目测O(N)+暴力更新 5min写完 P3842 [TJOI2007] ...

  9. DP百题练(一)

    目录 DP百题练(一) 线性 DP 简述 Arithmetic Progressions [ZJOI2006]物流运输 LG1095 守望者的逃离 LG1103 书本整理 CH5102 移动服务 LG ...

随机推荐

  1. python 获取当前运行的类名函数名

    import inspect def get_current_function_name(): return inspect.stack()[1][3] class MyClass: def func ...

  2. dev GridControl显示标题

    gridview:ShowViewCaption = TrueViewCation = "32435354354"

  3. C++11之nullptr

    [C++11空指针] 1.NULL的问题 class Test { public: void TestWork(int index) { std::cout << "TestWo ...

  4. 读取properties文件并获取属性值

    1.Properties与ResourceBundle 两个类都可以读取属性文件中以key/value形式存储的键值对,ResourceBundle读取属性文件时操作相对简单. 2.Propertie ...

  5. 【BZOJ4566】找相同字符【后缀自动机】

    题意 给定两个字符串,求两个字符串相同子串的方案数. 分析 那么将字符串s1建SAM,然后对于s2的每个前缀,都在SAM中找出来,并且计数就行. 我一开始的做法是,建一个u和len,顺着s2跑SAM, ...

  6. SpringData JPA整理

    一 首先熟悉几种jpa中的接口Repository,CrudRepository,PagingAndSortingRepository,JpaRepository,JpaSpecificationEx ...

  7. 万能头文件#include<bits/stdc++.h>

    最近在打cf时赛后翻阅别人的代码总是会发现一个陌生而奇怪的头文件#include<bits/stdc++.h> 奇怪之处就在于基本上所有的代码只要用了这个头文件就不再写其他头文件了. 百度 ...

  8. spring之IOC容器创建对象

    1.术语了解 1.1组件/框架设计 侵入式设计 引入了框架,对现有的类的结构有影响:即需要实现或继承某些特定类. 例如: Struts框架非侵入式设计 引入了框架,对现有的类结构没有影响. 例如:Hi ...

  9. JSON_UNESCAPED_UNICODE

    JSON_UNESCAPED_UNICODE(中文不转为unicode)

  10. Spring.net init-method destroy-method

    <object id="exampleInitObject" type="Examples.ExampleObject" init-method=&quo ...