csu

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1538

很奇妙的一个题,开始没有思路.问了别人才知道.

题目的意思可以理解成上图中,从0点开始向右走,走到n+1点需要最少步数。思路是:因为走某些点时,必须先走另外一点,所以可以用贪心算法,将限制条件可以看成区间,求出它们的并集,如下图:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<queue>
 6 #include<cmath>
 7 #include<cstdio>
 8 using namespace std;
 9 const int maxn=1010;
10 int l[maxn],r[maxn],vis[maxn];
11 int c[maxn],d[maxn];
12 int main()
13 {
14     //freopen("a.txt","r",stdin);
15     int n,m;
16     while(~scanf("%d%d",&n,&m))
17     {
18         for(int i=1;i<=n;i++)
19             l[i]=i,r[i]=i;
20         memset(vis,0,sizeof(vis));
21         for(int i=0;i<m;i++)
22         {
23             scanf("%d%d",&c[i],&d[i]);
24             l[d[i]]=c[i];
25             r[c[i]]=d[i];
26             vis[c[i]]=vis[d[i]]=1;
27         }
28         int flag=0,last=0,ans=0,lx,rx;
29         for(int i=1;i<=n;i++)
30         {
31             if(!vis[i]) continue;  
32             //printf("%d
",ans);
33             if(!flag)  //从起始点到第一个被标记的点 
34             {
35                 flag=1;
36                 ans+=i-last;
37                 lx=i;   
38                 rx=r[i]; //向右延伸
39             }
40             else if(rx<l[i])
41             {
42                // printf("%d %d
",last,lx);
43                 ans+=i-rx;   
44                 ans+=(rx-lx)*3;
45                 last=i;
46                 lx=l[i];
47                 rx=r[i];
48             }
49             else if(rx>l[i]&&rx<r[i]) //有交集 求出交集 
50             {
51                 rx=r[i];
52             }
53         }
54         //printf("%d %d %d
",rx,lx,last);
55         ans+=(n+1-rx);
56         ans+=3*(rx-lx);
57         printf("%d
",ans);
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/nowandforever/p/4608316.html