#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1e5+10,M=0,Z=1e9+7,ms63=0x3f3f3f3f;
int casenum,casei;
int n,x,y;
pair<int,int>a[N];
int res[N];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;++i)scanf("%d%d",&a[i].first,&a[i].second);
sort(a+1,a+n+1);
a[n+1].first=-1;
res[0]=0;
//枚举每个位置作为最后不被破坏的位置
int ans=1e9;
for(int i=1;i<=n;++i)
{
int last=lower_bound(a+1,a+i,MP(a[i].first-a[i].second,-1))-1-a;//最后一个不被它破坏的位置
res[i]=res[last]+1;
gmin(ans,n-res[i]);
}
printf("%d\n",ans);
}
return 0;
}
/*
【trick&&吐槽】
我竟然卡在这道题上这么久!
在你想不到好的做法的时候,试试看最原始的暴力!
【题意】
有n(1e5)个灯塔,每个灯塔有属性(坐标a[i].first,向左的照射范围a[i].second),所有灯塔坐标两两不同。
我们从右往左,对于每个灯塔,其所照射到的所有灯塔都被认定为被破坏。
我们现在可以在所有灯塔的右边,布置一个新的灯塔,位置和范围任意定。
问你,是否有一种布置灯塔的方案,可以使得被破坏的灯塔数尽可能少,并输出最少破坏的灯塔数。
【类型】
贪心 DP思维
【分析】
尝试暴力!
我们发现,我们新灯塔的功能,其实是使得最右面的若干个灯塔失效。
意思就是,使得第1,2,3,4,5,……,n个灯塔,作为没被破坏的最后一个灯塔。
我们能否算出第i个灯塔,作为没被破坏的最后一个灯塔条件下的答案呢?
这个显然是很容易做到的。我们可以按照灯塔坐标对这n个灯塔做升序排序。
然后,对于第i个灯塔,它可以破坏掉的区间范围是a[i].first-a[i].second
设最后一个破坏掉的位置为pos,那么我们在a中做二分, 查找第一个位置比pos小的。之前的便全部保留了。
基于这个方式,我们就可以在O(nlogn)的条件下,枚举最后一个没被破坏的灯塔,暴力过掉这道题了。
【时间复杂度&&优化】
O(nlogn)
*/
【Codeforces Round 336 (Div 2) C】【贪心 DP思维】Chain Reaction 每个灯塔位置为a[]破坏b[]范围所有灯塔 设置一个灯塔使得最多灯塔被保留
最新推荐文章于 2021-04-13 20:26:56 发布