题意
给定N个灯塔,灯塔一字排开,输入每个灯塔的坐标和灯光范围,如果一个灯塔被激活,那么灯塔左边(左边较小的方向)在灯光范围以内的塔都会被毁掉,现在可以在所有灯塔的最右边新建一座灯塔,新灯塔的坐标和灯光范围任意,之后所有灯塔从右往左依次激活,如果灯塔已经被毁,就不会激活,问如何选择新建灯塔的位置和灯光范围,可以使最后被毁掉的灯塔最少
题解
DP,激活一座灯塔,左边灯光范围的塔会被毁掉,剩下的塔中的第一座激活,就可以递推了
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
typedef long long LL;
struct P
{
int pos;
int r;
};
struct P p[maxn+5];
int dp[maxn+5];
bool cmp(const struct P &a,const struct P &b)
{
return a.pos<b.pos;
};
int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif
int n;
scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%d%d",&p[i].pos,&p[i].r);
}
sort(p+1,p+1+n,cmp);
dp[0]=n;
int ans=n;
for (int i=1;i<=n;++i)
{
struct P temp=(P){p[i].pos-p[i].r,0};
int k=lower_bound(p+1,p+i+1,temp,cmp)-p;
dp[i]=dp[k-1]-1;
if (dp[i]<ans) ans=dp[i];
}
printf("%d\n",ans);
}
代码里第一次试着用lower_bound对结构体进行二分搜索,基础还是不行啊……