Poj--1944(贪心,枚举)

2014-12-10 00:23:40

思路:这题的思路很精巧,看了题解。。。感觉别人写的好飘逸,几十ms。。

  自己YY了下,100多ms,不过思路还算清晰。

  首先考虑,最后肯定不会是一个环(因为随便去掉一条边都能得到更优的解),对于一个需求[a,b],要么直接走a->b,要么1->a , b->n->1,从起点走过去。

  由于至少有一个断点,而且我们发现如果存在一个断点,那么对于每个需求,它的连接方向就确定了(总有一个方向的走法被断点截断),所以就可以通过枚举断点的位置来确定出每个需求的走法,然后用贪心扫一遍最少需要的边。用 d[i] = j 来表示 i 这个点最远需要连到 j。

 1 /*************************************************************************
 2     > File Name: 1944.cpp
 3     > Author: Natureal
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 09 Dec 2014 11:05:58 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 const int maxn = 10010;
27 
28 int N,P,d[maxn];
29 struct node{
30     int l,r;
31 }t[maxn];
32 
33 bool cmp(node a,node b){
34     if(a.l == b.l)
35         return a.r < b.r;
36     return a.l < b.l;
37 }
38 
39 int main(){
40     scanf("%d%d",&N,&P);
41     for(int i = 1; i <= P; ++i){
42         scanf("%d%d",&t[i].l,&t[i].r);
43         if(t[i].l > t[i].r)
44             swap(t[i].l,t[i].r);
45     }
46     sort(t + 1,t + P + 1,cmp);
47     int ans = INF;
48     for(int k = 1; k <= N; ++k){
49         //枚举断点,断在[i-1,i]这条边上。
50         memset(d,0,sizeof(d));
51         int pos = 0,res = 0;
52         for(int i = 1; i <= P; ++i){
53             if(t[i].l < k && k <= t[i].r){
54                 d[1] = max(d[1],t[i].l);
55                 d[t[i].r] = N;
56                 res = 1;
57             }
58             else{
59                 d[t[i].l] = max(d[t[i].l],t[i].r);
60             }
61         }
62         for(int i = 0; i <= N; ++i){
63             if(i > pos) pos = i;
64             if(d[i] > pos){
65                 res += d[i] - pos;
66                 pos = d[i];
67             }
68         }
69         ans = min(ans,res);
70     }
71     printf("%d\n",ans);
72     return 0;
73 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4154524.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值