[题目传送门] ---------------> http://codeforces.com/problemset/problem/608/C
[题目]
There are n beacons located at distinct positions on a number line. The i-th beacon has position ai and power level bi. When the i-th beacon is activated, it destroys all beacons to its left (direction of decreasing coordinates) within distance bi inclusive. The beacon itself is not destroyed however. Saitama will activate the beacons one at a time from right to left. If a beacon is destroyed, it cannot be activated.
Saitama wants Genos to add a beacon strictly to the right of all the existing beacons, with any position and any power level, such that the least possible number of beacons are destroyed. Note that Genos's placement of the beacon means it will be the first beacon activated. Help Genos by finding the minimum number of beacons that could be destroyed.
The first line of input contains a single integer n (1 ≤ n ≤ 100 000) — the initial number of beacons.
The i-th of next n lines contains two integers ai and bi (0 ≤ ai ≤ 1 000 000, 1 ≤ bi ≤ 1 000 000) — the position and power level of the i-th beacon respectively. No two beacons will have the same position, so ai ≠ aj if i ≠ j.
Print a single integer — the minimum number of beacons that could be destroyed if exactly one beacon is added.
4
1 9
3 1
6 1
7 4
1
7
1 1
2 1
3 1
4 1
5 1
6 1
7 1
3
[思路]
DP + 二分
读入灯塔数据,位置和能量到一个pair中然后按升序sort。
dis[i] 代表 dis[i] 被点亮时,被摧毁的左边的灯塔的数量。最左边的灯塔能量不管是多少都没有摧毁的东西 所以 dis[0] = 0;
接下来进行状态转移(for k = 1 ; k < n ; k++),对于第k个灯塔都从前一个 “没有被k灯点亮而摧毁的灯塔处” 进行转移,加上 点亮第k个灯塔所摧毁的灯塔数,如果发现第k个灯塔左边所有的灯塔都被摧毁了,则 dp[k] = k;
分析得,题中要求加入一个最右边的灯塔,其实意思是让我们 “从一开始的序列中 直接从最右边开始去掉若干灯塔当作被摧毁 ” 然后剩下的序列继续进行点亮操作后算出被摧毁的灯塔数目。 求出所有可能的方案中的最小数量。
枚举去掉最右边的0个灯塔,一个灯塔,两个灯塔。。。。t 个灯塔
当去掉 t 个灯塔时, 被摧毁的灯塔总数就是 t + dis[n - 1 - t];
找出最小即可。
[代码]
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 #define pos first 7 #define power second 8 #define MAX 100010 9 #define PLL pair<int,int> 10 #define LL long long 11 12 LL dis[MAX]; 13 PLL node[MAX]; 14 LL min(LL a , LL b) {return a < b ? a : b;} 15 16 int main() 17 { 18 int n; 19 cin >> n; 20 dis[0] = 0; 21 /////////////////// 22 for(int i = 0 ; i < n ; i++) 23 { 24 cin >> node[i].pos >> node[i].power; 25 } 26 sort(node , node + n); 27 for(int i = 1 ; i < n ; i++) 28 { 29 int curpos = node[i].pos; 30 int curpower = node[i].power; 31 int in_pos = lower_bound(node , node + n , make_pair(node[i].pos - node[i].power,0)) - node; 32 if(in_pos > 0) 33 { 34 dis[i] = dis[in_pos - 1] + (i - in_pos); 35 } 36 else 37 { 38 dis[i] = i; 39 } 40 } 41 LL ans = n; 42 for(int i = 0 ; i < n ; i++) 43 { 44 dis[i] = dis[i] + (n - i - 1); 45 ans = min(dis[i] , ans); 46 } 47 cout << ans << endl; 48 return 0; 49 50 }