题意
有个怪物,每只怪物的出现时间是,血量是。魔法师可以从点伤害开始施加魔法,每次伤害之后可以增加一点伤害,但如果不施法,下一次施法伤害会重新从点伤害开始累计。问最少需要的魔法值总和。
解法
水题一发。
把每只怪物当成线段,需要开始从开始施法累积的时间点为左端点,出现时间为右端点,然后当成线段覆盖做就好。
记得多组数据。
附代码:
#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;
}