题目
问题描述
有k个洞穴,每个洞穴里面都有 a i a_i ai只怪物且每个洞穴中的怪物是以特定的顺序排列,勇士的任务是清除所有怪物,而且每消灭一只怪物自身的战斗力都会提升一点,当勇士选择进入一个洞穴后,需要按照上面的顺序逐一挑战洞穴中的每个怪物,只有勇士的战斗力高于怪物才可以消灭怪物,问勇士可以消灭所有怪物所需要的最小初始战斗力。
分析
我们有两个问题:
第一个是求出成功走出一个洞穴所需要的最小初始战斗力;
第二个是在已知走出每个洞穴所需最小初始战斗力和洞穴怪物数(可得知走出洞穴时的战斗力)的情况下,求出可以成功走出每个洞穴所需的最小初始战斗力。
问题一:
已知序列
{
a
0
,
a
1
,
a
2
,
a
3
…
…
a
n
−
1
}
\{a_0,a_1,a_2,a_3……a_{n-1}\}
{a0,a1,a2,a3……an−1},不妨设初始战斗力为
x
x
x,那么
x
x
x就需要满足以下的不等式:
x
+
0
>
a
0
x+0>a_0
x+0>a0
x
+
1
>
a
1
x+1>a_1
x+1>a1
……
x
+
n
−
1
>
a
n
−
1
x+n-1>a_{n-1}
x+n−1>an−1
转化为代码就是
int ma=0;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i]-i>ma){
ma=a[i]-i;
}
}
b[s].x=ma+1;
b[s].y=n;
问题二:
设可以成功走出每个洞穴所需的最小初始战斗力为p,将洞穴按照进入的初始战斗力要求从小到大排列(感觉是贪心的做法),尽可能最大化利用每个洞穴的通关buff,满足的不等式如下:
p
+
0
>
b
0
p+0>b_0
p+0>b0
p
+
n
0
>
b
1
p+n_0>b_1
p+n0>b1
p
+
n
0
+
n
1
>
b
2
p+n_0+n_1>b_2
p+n0+n1>b2
……
p
+
∑
i
=
0
k
−
2
n
i
>
b
k
−
1
p+\sum_{i=0}^{k-2}n_i>b_{k-1}
p+∑i=0k−2ni>bk−1
转为代码就是:
ans=len=0;
sort(b,b+k,cmp);
for(int i=0;i<k;i++){
ans=max(ans,b[i].x-len);
len+=b[i].y;
}
代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
int a[N];
int ans;
int len;
struct node{
int x;//最小初始战斗力
int y;//怪物数
};
node b[N];
void f(int s){
int n;
cin>>n;
int ma=0;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i]-i>ma){
ma=a[i]-i;
}
}
b[s].x=ma+1;
b[s].y=n;
}
int cmp(node a,node b){
return a.x<b.x;
}
int main(){
int t;
cin>>t;
while(t--){
int k;
cin>>k;
for(int i=0;i<k;i++){
f(i);
}
ans=len=0;
sort(b,b+k,cmp);
for(int i=0;i<k;i++){
ans=max(ans,b[i].x-len);
len+=b[i].y;
}
cout<<ans<<endl;
}
return 0;
}