poj 3069 贪心+区间问题

本文探讨了如何使用贪心算法解决Saruman指挥军队的问题,通过合理分配观测石(Palantirs)确保军队每个成员都能在一定范围内被观测到。通过排序和贪心策略,最小化所需观测石的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Saruman's Army
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5989 Accepted: 3056

Description

Saruman the White must lead his army along a straight path from Isengard to Helm’s Deep. To keep track of his forces, Saruman distributes seeing stones, known as palantirs, among the troops. Each palantir has a maximum effective range of R units, and must be carried by some troop in the army (i.e., palantirs are not allowed to “free float” in mid-air). Help Saruman take control of Middle Earth by determining the minimum number of palantirs needed for Saruman to ensure that each of his minions is within R units of some palantir.

Input

The input test file will contain multiple cases. Each test case begins with a single line containing an integer R, the maximum effective range of all palantirs (where 0 ≤ R ≤ 1000), and an integer n, the number of troops in Saruman’s army (where 1 ≤ n ≤ 1000). The next line contains n integers, indicating the positions x1, …, xn of each troop (where 0 ≤ xi ≤ 1000). The end-of-file is marked by a test case with Rn = −1.

Output

For each test case, print a single integer indicating the minimum number of palantirs needed.

Sample Input

0 3
10 20 20
10 7
70 30 1 7 15 20 50
-1 -1

Sample Output

2
4

Hint

In the first test case, Saruman may place a palantir at positions 10 and 20. Here, note that a single palantir with range 0 can cover both of the troops at position 20.

In the second test case, Saruman can place palantirs at position 7 (covering troops at 1, 7, and 15), position 20 (covering positions 20 and 30), position 50, and position 70. Here, note that palantirs must be distributed among troops and are not allowed to “free float.” Thus, Saruman cannot place a palantir at position 60 to cover the troops at positions 50 and 70.

本来以为一道小水题,后来还是做了两个多小时,,其实觉得这道题目还是有一点思维量的,将各个士兵的位置放入数组中,排序后,,标记完一个点后,要让下一个点尽可能的往右!!但是特别要注意,第一个标记的点不一定要在第一个士兵身上,,,所以

不能让第一个士兵成为标记点,,正确的贪心做法是:在当前为标记的点的情况下,

让覆盖其的标记点尽可能往右,,同时因为这个点可以覆盖右边的区域,所以下一个

未覆盖的起始点要在最考进该标记点而大于半径的那点上。

#include<iostream>
#include<cstdio>
#include<set>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1005];
int main()
{
    int ri,t;
    while(~scanf("%d %d",&ri,&t))
    {
        if(ri==-1&&t==-1)
            return 0;
        for(int i=1;i<=t;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+t+1);
        int cnt=0;
        int i=1,r=t;
        while(i<=t)
        {
           int s=a[i++];//s是当前最靠左的为标记点的位置
           while(i<=t&&a[i]-s<=ri)
                i++;
           int p=a[i-1];//标记点的位置
           while(a[i]-p<=ri&&i<=t)
                i++;//i为最靠进该标记点而大于半径的那点
           cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}


转载于:https://www.cnblogs.com/smilesundream/p/6642553.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值