码迷,mamicode.com
首页 > 其他好文 > 详细

P3842 [TJOI2007]线段

时间:2021-04-10 13:20:07      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:最小值   def   ace   else   线性dp   cond   return   href   ble   

原题链接

考察:线性dp

思路:

        这道题就和POJ 1661差不多.f[i][0/1]表示到达第i条线段的0(左),1(右)的最小距离.

        f[i][0] = min(f[i-1][0]+i-1条线左端点到i条线左端点的最短距离,f[i-1][1]+i-1条线右端点到第i条线左端点的最小值)

        同理右端点.

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 typedef pair<int,int> PII;
 5 const int N = 20010;
 6 int n,f[N][2];
 7 PII p[N];
 8 int getl(int x,int idx)//x到左点的最小值 
 9 {
10     int l = p[idx].first,r = p[idx].second,res = 0;
11     if(x<=l) res = 2*r-l-x;
12     else if(x>l&&x<r) res = min(x-l+(r-l)*2,r-x+r-l);
13     else res = x-l;
14     return res; 
15 }
16 int getr(int x,int idx)//x到右端点的最小值. 
17 {
18     int l = p[idx].first,r = p[idx].second,res = 0;
19     if(x<=l) res = r-x;
20     else if(x>l&&x<r) res = min(x-l+r-l,r-x+(r-l)*2);
21     else res = x+r-2*l;
22 }
23 int solve()
24 {
25     p[0].first = 1,p[0].second = 1;
26     for(int i=1;i<=n;i++)
27     {
28         int l = p[i-1].first,r = p[i-1].second;
29         f[i][0] = min(f[i-1][0]+getl(l,i),f[i-1][1]+getl(r,i));
30         f[i][1] = min(f[i-1][0]+getr(l,i),f[i-1][1]+getr(r,i));
31         if(i!=1) f[i][0]++,f[i][1]++;
32     }
33     int l = p[n].first,r = p[n].second;
34     int ans = min(f[n][0]+abs(n-l),f[n][1]+abs(n-r));
35     return ans;
36 }
37 int main() 
38 {
39     scanf("%d",&n);
40     for(int i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second);
41     int res = solve();
42     printf("%d\n",res);
43     return 0;
44 }

 

P3842 [TJOI2007]线段

标签:最小值   def   ace   else   线性dp   cond   return   href   ble   

原文地址:https://www.cnblogs.com/newblg/p/14638917.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!