题目大意:
给你 n 个数,要求你对这 n 个数中的某些数 pi 增大 x,使得对于任意
p
i
p
1
+
p
2
+
.
.
.
+
p
i
−
1
\frac {p~i~} {p~1~+p~2~+...+p~i-1~}
p 1 +p 2 +...+p i−1 p i ≤
k
100
\frac {k} {100}
100k,求所有 x 的和(最小的和)。
思路:
设我们增大的某个数为 pj。令 m =
p
i
p
1
+
p
2
+
.
.
.
+
p
i
−
1
\frac {p~i~} {p~1~+p~2~+...+p~i-1~}
p 1 +p 2 +...+p i−1 p i 。
若 j < i,增加 pj,m 减小。
若 j > i,增加 pj,m 不变。
若 j = i,增加 pj,m 增大。
如果增加的是 pj-1 而不是 pj,j = i时,m 就会减小了,j > i时,m 依然不变。
同理,如果增加的是 p0,不论 j 和 i 什么关系,m 只会减小。
综上,贪心策略就是:只增加 p0。
用 s[i-1] 表示 p1 +p2+…+pi-1
p i p 1 + x + p 2 + . . . + p i − 1 \frac {p~i~} {p~1~+ x +p~2~+...+p~i-1~} p 1 +x+p 2 +...+p i−1 p i ≤ k 100 \frac {k} {100} 100k
pi * 100 ≤ k * (s[i-1] + x)
p i ∗ 100 k \frac {p~i~ * 100} {k} kp i ∗100 ≤ s[i-1] + x
⌈ p i ∗ 100 − k ∗ s [ i − 1 ] k \frac {p~i~ * 100 - k*s[i-1]} {k} kp i ∗100−k∗s[i−1] ⌉ ≤ x
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 105;
LL a[N],s[N];
int n,k;
int main()
{
int t;
cin >> t;
while(t--)
{
memset(s,0,sizeof s);
cin >> n >> k;
for(int i=1; i<=n; i++) cin >> a[i];
for(int i=1; i<=n; i++) s[i] = s[i-1] + a[i]; //前缀和
LL res = 0;
for(int i=2; i<=n; i++)
{
res = max(res,(100 * a[i]- s[i-1] * k + k - 1) / k );
//只取最大的x即可,最大x可以让所有的 m 满足条件。
}
cout << res << endl;
}
}