Codeforces Round #608 (Div. 2) D Portals

#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int n,m,k;
int a[N],b[N],c[N];//攻破所需人数,获得人数,奖励得分
int l[N],d[N],f[N],h[N];//可以扔掉兵攻占i的最晚的点,累加到i的上限兵人数,这个点可以扔掉的兵数
int idx[N];
int ans;
//看看这题有没有解,顺便求个前缀和:d[i]=b[1]+...+b[n]
bool check() {
    int p=k;
    for(int i=1; i<=n; i++) {
        if(p<a[i]) return 1;
        p+=b[i],d[i]=p;//d[i]累加到i点为止的上限兵人数
    }
    return 0;
}

bool cmp(int a,int b) {//按照分数的大小 排序
    return c[a]>c[b];
}
//判断这个点能不能扔兵
bool check2(int x) {
    for(int i=n; i>=x; i--) {
        if(h[i]==0) return 0;//如果后面有个点开始不能扔兵的话这个点也不能扔兵
    }
    return 1;
}
int main() {
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1; i<=n; i++) {
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
        l[i]=i,idx[i]=i;//初始化idx,以及扔兵位置
    }
    //读入每个portal最晚在哪里留下防守的
    for(int i=1; i<=m; i++) {
        int x,y;
        scanf("%d%d",&x,&y);
        l[y]=max(l[y],x);
    }
    //判断题目是否有解
    if(check()) {
        puts("-1");
        return 0;
    }
    //计算到这个点可以扔的兵数
    a[n+1]=0;
    for(int i=1; i<=n; i++) {
        h[i]=d[i]-a[i+1];
    }
    
    //将idx按照分数的大小排序
    sort(idx+1,idx+1+n,cmp);//把攻占分数从大到小排序
    
    for(int i=1; i<=n; i++) {
        //先取出分数最大的
        int x=idx[i];
        if(check2(l[x])) {
            //先判断这个点能不能留下士兵,因为要确保后面的城堡都能攻下来
            //如果能的话,那么后面的城堡的h都要减一
            for(int j=l[x]; j<=n; j++) h[j]--;
            ans+=c[x];
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12068825.html
今日推荐