P3842 [TJOI2007] 线段

 

 

题目传送门

题意:你必须经过每一行的几条线段,求从起点到终点的最短路思路:

DP!,首先,每一层的最优肯定是由上一层限制的最左端点或者最右端点下来将此行走完,那么可得转移方程:
  1.f[i][0]表示走完第i行且停在第i行的左端点最少用的步数
  2.f[i][1]表示走完第i行且停在第i行的右端点最少用的步数
那么转移:走完当前行,停到左端点,那么一定是从右端点过来的,那么从上一行左端点转移的话就是  f[i][0]=abs(上一行左端点的坐标-本行右端点的坐标+本行线段长度);停到右端点的方法可如法炮制。

最后就是炒鸡分类讨论

蜜汁代码(居然A了):

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e4+9;
 4 int l[maxn],r[maxn],dp[maxn][3];
 5 int dist(int a,int b)
 6 {
 7     return abs(a-b);
 8 }
 9 int main()
10 {
11     ios::sync_with_stdio(0);
12     int n,t;
13     cin>>n;
14     for(int i=0;i<n;i++) cin>>l[i]>>r[i];
15     dp[0][1]=dist(1,r[0]);
16     dp[0][0]=dist(1,r[0])+dist(l[0],r[0]);
17     for(int i=1;i<n;i++)
18     {
19         for(int j=0;j<=1;j++)
20         {
21             int d1,d2;
22             if(j==0)
23             {
24                int x=l[i-1],y=r[i-1];
25                if(l[i-1]>=l[i]&&l[i-1]<=r[i]) d1=(2*dist(r[i],l[i-1])+dist(l[i-1],l[i]));
26                else if(l[i-1]>r[i]) d1=dist(l[i],r[i])+dist(r[i],l[i-1]);
27                else d1=dist(l[i],r[i])*2+dist(l[i-1],l[i]);
28                l[i-1]=r[i-1];
29                d2=d1;
30                if(l[i-1]>=l[i]&&l[i-1]<=r[i]) d1=(2*dist(r[i],l[i-1])+dist(l[i-1],l[i]));
31                else if(l[i-1]>r[i]) d1=dist(l[i],r[i])+dist(r[i],l[i-1]);
32                else d1=dist(l[i],r[i])*2+dist(l[i-1],l[i]);
33                l[i-1]=x;
34                r[i-1]=y;
35                if(d2+dp[i-1][0]<d1+dp[i-1][1]) dp[i][j]=dp[i-1][0]+d2;
36                else dp[i][j]=dp[i-1][1]+d1;
37             }
38             else
39             {
40                int x=l[i-1],y=r[i-1];
41                if(l[i-1]>=l[i]&&l[i-1]<=r[i]) d1=(2*dist(l[i],l[i-1])+dist(l[i-1],r[i]));
42                else if(l[i-1]<r[i]) d1=dist(l[i],r[i])+dist(l[i],l[i-1]);
43                else d1=dist(l[i],r[i])*2+dist(l[i-1],r[i]);
44                l[i-1]=r[i-1];
45                d2=d1;
46                if(l[i-1]>=l[i]&&l[i-1]<=r[i]) d1=(2*dist(l[i],l[i-1])+dist(l[i-1],r[i]));
47                else if(l[i-1]<r[i]) d1=dist(l[i],r[i])+dist(l[i],l[i-1]);
48                else d1=dist(l[i],r[i])*2+dist(l[i-1],r[i]);
49                if(d2+dp[i-1][0]<d1+dp[i-1][1]) dp[i][j]=dp[i-1][0]+d2;
50                else dp[i][j]=dp[i-1][1]+d1;
51                l[i-1]=x;
52                r[i-1]=y;
53             }
54         }
55     }
56     if(dp[n-1][0]+(n-l[n-1])>(n-r[n-1]+dp[n-1][1])) cout<<(n-r[n-1]+dp[n-1][1])+n-1<<endl;
57     else cout<<dp[n-1][0]+(n-l[n-1])+n-1<<endl;
58     return 0;
59 }
复制代码
posted @   王浩泽  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示