http://codeforces.com/contest/608/problem/C
//ans【i】,表示 以第i灯作为最后一个灯,保存下来的灯数,
计算ans[i]方法就是 xx=tm[i].l-tm[i].r //表示第i个灯最左的杀伤范围,二分找到第一个小于这个杀伤范围的灯B,ans[i]= ans【B灯】+1; 有点类似DP的递推
计算出n个ans值,复杂度nlogn
n-max_ans就是 最小的被杀掉的灯数了
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <stack> #include <vector> #include <iostream> using namespace std; struct node { __int64 l,r; bool operator <(const node &b) const { return l<b.l; } }; node tm[100005]; __int64 ans[1000005]; int main() { __int64 i,j,k; __int64 n; scanf("%I64d",&n); for (i=1;i<=n;i++) { scanf("%I64d%I64d",&tm[i].l,&tm[i].r); } sort(tm+1,tm+1+n); ans[tm[1].l]=1; node tmp; for (i=2;i<=n;i++) { __int64 xx=tm[i].l-tm[i].r; tmp.l=xx; __int64 it=lower_bound(tm+1,tm+1+n,tmp)-tm;//二分找到最后一个未被破坏的灯 it--; if (it==0)//如果不存在,即只剩下该灯本身 ans[tm[i].l]=1; else ans[tm[i].l]=ans[tm[it].l]+1;//那么剩下的灯数由原来的+1(本身) } __int64 maxx=ans[tm[1].l]; //ans【i】,以第i灯作为最后一个灯,保存下来的灯数,选一个最大的 for (i=1;i<=n;i++) { if (ans[tm[i].l]>maxx) maxx=ans[tm[i].l]; } printf("%I64d\n",n-maxx); return 0; }