POJ-3096-贪心

今天开始恢复训练(其实省赛完了玩了好久),发现了这道一年前做过的题,神特么没写出来QAQ。

我想的是选择覆盖的点越多越好的点,然后拼命写每个点覆盖了多少个点然后贪心...就是没稍微转一下,覆盖的最多那不就是越远越好么(在r的范围内)...所以这个题:从第一个没处理的点开始向右找最远的,能覆盖的点,设为s,那么这个s点就是第一个标记点,然后从s开始向右找最远的能覆盖的点,那么这个点就是第一个覆盖区间里最后一个点。依次操作即可。

我写的三层循环但是实际上复杂度还是O(N)。

#include <cstring>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn=1e3+10;
int rr,n;
int arr[maxn],vis[maxn];

int main()
{
    while(scanf("%d%d",&rr,&n) && rr!=-1 && n!=-1)
    {
        memset(vis,-1,sizeof(vis));
        for(int i=1; i<=n; i++)
            scanf("%d",&arr[i]);
        sort(arr+1,arr+1+n);
        int ans=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(arr[i]+rr<arr[j])
                {
                    for(int k=j;k<=n;k++)
                    {
                        if(arr[j-1]+rr<arr[k])
                        {
                            ans++;
                            i=k-1;
                            break;
                        }
                    }
                    break;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/alusang/article/details/80356517