万恶之源

题意

给定若干个点的坐标,与范围R。每个点可以选择是否标记,标记后这个点的左右范围R内的所有点也会被标记,求为使所有点被标记,我们要主动标记多少个点。

思路

这题总感觉可以用搜索做,毕竟每个点的状态要么是1要么是0。但这是书上贪心的例题,那肯定得用贪心做啦。

贪心的原则是什么呢?

错解

首先我们的目标是尽可能少的标记,因此我们当然可以希望每次一次性标记的点越多越好,那么我们是不是可以遍历每个点,每次选择一次性标记数最多的点来标记呢?显然不行 我们可以看一下这个数据

1 9
1 2 2 3 3 3 4 4 5

显然在这种规则下程序会选择标记3,一口气标记了7个数字呢!然后呢,望不到彼此的1和5只能自己标记自己,因此最后我们主动标记了3个数。显然不是最优解。(其实这就是我的原始想法)

正解

我们可以从最左边开始考虑。在上述例子的条件下,我们肯定不会标记“1”,因为这样会浪费左边的范围,即标记“2”是优于标记“1”的。但是标记“3”就不是最优解了,为什么呢?因为标记“3”覆盖不到“1”,也就是留了个孤零零的元素没标记,这样子我们不得不单独的标记"1"。总而言之,标记“1”会浪费左边的空间,所以我们会试着选择标记“2”以及后面的元素,但是标记“3”不能照顾到”1“,带来了额外的成本,因此我们会选择标记2。所以我们希望被标记的点尽量靠右,不浪费左边的空间,但是也不能不覆盖最左边未标记的元素(即留空子)。

因此,贪心的原则应该是这样。

每次给最左边未标记的点的R范围内,最靠右的点标记。然后不断重复这一过程。

代码实现

书上的代码

int N, R;
int X[MAXN]; void solve(){
sort(X, X + N); int i = 0, ans = 0;
while(i < N){
int s = X[i++];//s是没有被覆盖的最左侧的位置
while(i < N && X[i] <= s + R) i++;
//一直向右前进,直到到达距离s的距离严格大于R的点(此处用的是小于等于号)
//相当于拓展p点的左侧 int p = X[i - 1];//p是新加上标记的点的位置,因为X[i]是接触不到s的
while (i < N && X[i] <= p + R) i++;
//一直向右前进,直到到达距离p的距离严格大于R的点
//相当于拓展p点的右侧 ans++;
}
printf("%d\n", ans);
}

我的代码

int r, n;
int troop[2000];//存储每只队伍的坐标 sort(troop, troop + n);
int tag = 0, ans = 0;////tag是没有被覆盖的最左侧的位置
troop[n] = 0x3f3f3f3f;//哨兵元素
for (int i = 0; i <= n; i++)
{
if (troop[i] - r > troop[tag]) {
ans++;
//标记点+1,没有明说,但标记的是i - 1
while (troop[i - 1] + r >= troop[tag]) tag++;
//更新标记点的右侧,也就是更新标记点的位置
}
//printf("%d---%d---%d\n", troop[i], troop[tag], ans);
}
printf("%d\n", ans);

比较一下

首先二者的思路是一致的。感觉区别在于书上的代码是一股气从左冲到右,而我的是一个一个检查,延迟标记(这也是为什么有一个哨兵的原因)

问题

我的问题主要在于一开始没有设置一个哨兵元素,然后我用很多if语句去判断各种情况来修补bug,但是修修补补终究不能AC。后来意识到标记不是即时的,才设置了一个哨兵元素,结果之前的if语句全部可以删掉,完美AC。可能一开始的方向就很重要吧。

历史提交

参考书籍:《挑战程序设计竞赛》

贪心-Saruman‘s Army POJ - 3069的更多相关文章

  1. Q - Saruman's Army POJ - 3069

    Saruman the White must lead his army along a straight path from Isengard to Helm's Deep. To keep tra ...

  2. Saruman's Army (POJ 3069)

    直线上有N个点.点i的位置是Xi.从这N个点中选择若干个,给它们加上标记.对每一个点,其距离为R以内的区域里必须又带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点).在 ...

  3. POJ 3617 Best Cow Line ||POJ 3069 Saruman's Army贪心

    带来两题贪心算法的题. 1.给定长度为N的字符串S,要构造一个长度为N的字符串T.起初,T是一个空串,随后反复进行下面两个操作:1.从S的头部删除一个字符,加到T的尾部.2.从S的尾部删除一个字符,加 ...

  4. POJ 3069 Saruman's Army(贪心)

     Saruman's Army Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  5. poj 3069 Saruman's Army(贪心)

    Saruman's Army Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Tot ...

  6. poj 3069 Saruman's Army 贪心模拟

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18794   Accepted: 9222 D ...

  7. POJ 3069 Saruman's Army(萨鲁曼军)

    POJ 3069 Saruman's Army(萨鲁曼军) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] Saruman ...

  8. poj 3069 Saruman's Army

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8477   Accepted: 4317 De ...

  9. POJ 3069:Saruman's Army

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13242   Accepted: 6636 D ...

随机推荐

  1. 动态规划精讲(一)LC 最长递增子序列的个数

    最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7]输出: 2解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, ...

  2. PHP中的MySQLi扩展学习(六)MySQLI_result对象操作

    在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容.它的作用其实就是一个查询的结果集.不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查 ...

  3. django url配置-反向解析-视图函数-HttpRequest对象-HttpResponse对象-cookies-session-redis缓存session

    """ --视图概述:-- 作用:视图接受WEB请求,并响应WEB请求 本质:视图就是一个python中的函数 响应: 1.网页: 一.重定向 二.错误视图 400,50 ...

  4. disruptor笔记之四:事件消费知识点小结

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. JS获取contextPath的方法

    function getContextPath() { var pathName = document.location.pathname;    var index = pathName.subst ...

  6. Douban Top 250爬虫

    # Ref: https://fishc.com.cn/forum.php?mod=viewthread&tid=101887&extra=page%3D1%26filter%3Dty ...

  7. mysql从零开始之MySQL LIKE 子句

    MySQL LIKE 子句 我们知道在 MySQL 中使用 SQL SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录. WHERE 子句中可以 ...

  8. firewalld dbus接口使用指南

    firewalld,一个基于动态区的iptables/nftables守护程序,自2009年左右开始开发,最新版本 - 防火墙0.6.3 - 发布于2018年10月11日.主要的开发人员是托马斯·沃纳 ...

  9. mysql int(3)与int(10)的数值范围相同吗?

    提问: mysql的字段,unsigned int(3), 和unsinged int(6), 能存储的数值范围是否相同.如果不同,分别是多大? 回答: 不同,int(3)最多显示3位无符号整体,in ...

  10. 从commons-beanutils反序列化到shiro无依赖的漏洞利用

    目录 0 前言 1 环境 2 commons-beanutils反序列化链 2.1 TemplatesImple调用链 2.2 PriorityQueue调用链 2.3 BeanComparator ...