Codeforces Round #336 C

Chain Reaction

题意:给一个n,然后n组ai bi,表示在ai位置上有一个信标,当它杯激发时会攻击左边bi(包括)范围的其他信标,如果他被破坏,则不会被激活,信标是从右到左依次激活的,现在你可以在任意一个位置放置一个信标,可以给它一个任意的攻击范围,且它是第一个被激活的,求最少可以破坏几个信标

思路:增加的信标一定是最右边,dp[i]表示位置为i的信标保留(如果有的话),大于i的信标全部破坏,所留下的信标个数,则可以得到dp[i]=dp[i-v-1]+1,v表示位置i的信标的攻击范围,注意一些细节就是了,比如i-v-1<0 等等

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int N=1e5+100;
int n,mx,ans=0,a[N],b[N],dp[10*N];
map<int,int> M1,M;
int main(){
    cin>>n;
    for(int i=1; i<=n; ++i){
        cin>>a[i]>>b[i];
        mx=max(mx,a[i]);
        M[a[i]]++;
        M1[a[i]]=b[i];
    }
    for(int i=0; i<=mx; ++i){
        if(M[i]){
            int p=i-M1[i]-1;
            if(p<0){
                dp[i]=1;
            }
            else dp[i]=dp[p]+1;
        }
        else if(i==0) dp[i]==0;
        else dp[i]=dp[i-1];
        ans=max(ans,dp[i]);
    }
    cout<<n-ans;
    return 0;
}
/*
4
1 9
3 1
6 1
7 4
7
1 1
2 1
3 1
4 1
5 1
6 1
7 1
*/
原文地址:https://www.cnblogs.com/max88888888/p/7106270.html