题意

nn个怪物,每只怪物的出现时间是kik_i,血量是hih_i。魔法师可以从11点伤害开始施加魔法,每次伤害之后可以增加一点伤害,但如果不施法,下一次施法伤害会重新从11点伤害开始累计。问最少需要的魔法值总和。

解法

水题一发。

把每只怪物当成线段,需要开始从11开始施法累积的时间点为左端点,出现时间为右端点,然后当成线段覆盖做就好。

记得多组数据。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define max(a,b) (a>b?a:b)
#define MAXN 110
using namespace std;
int n;
long long ans;
struct node{
    int k,h,l;
    bool flag;
    friend operator <(const node &u,const node &v){
        return u.l==v.l?(u.k<v.k):(u.l<v.l);
    }
}a[MAXN];
char tp[100000],*p1=tp,*p2=tp;
inline char get_char(){
	return p1==p2&&(p2=(p1=tp)+fread(tp,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=get_char();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=get_char();}
    return date*w;
}
inline long long getans(long long x){return x*(x+1)/2LL;}
void work(){
    for(int i=1;i<=n;i++)if(a[i].flag){
        for(int j=i+1;j<=n&&a[j].l<=a[i].k;j++){
            a[i].k=max(a[i].k,a[j].k);
            a[j].flag=false;
        }
        ans+=getans(a[i].k-a[i].l+1);
    }
    printf("%lld\n",ans);
}
void init(){
    ans=0;
    memset(a,0,sizeof(a));
    n=read();
    for(int i=1;i<=n;i++)a[i].k=read();
    for(int i=1;i<=n;i++){
        a[i].h=read();
        a[i].l=a[i].k-a[i].h+1;
        a[i].flag=true;
    }
    sort(a+1,a+n+1);
}
int main(){
    //freopen("solve.in","r",stdin);
    //freopen("solve.out","w",stdout);
    int t=read();
    while(t--){
        init();
        work();
    }
    return 0;
}