题意
Let’s call a list of positive integers a0,a1,…,an−1a0,a1,…,an−1 a power sequence if there is a positive integer cc, so that for every 0≤i≤n−10≤i≤n−1then ai=ciai=ci.
Given a list of nn positive integers a0,a1,…,an−1a0,a1,…,an−1, you are allowed to:
- Reorder the list (i.e. pick a permutation pp of {0,1,…,n−1}{0,1,…,n−1} and change aiai to apiapi), then
- Do the following operation any number of times: pick an index ii and change aiai to ai−1ai−1 or ai+1ai+1 (i.e. increment or decrement aiai by 11) with a cost of 11.
Find the minimum cost to transform a0,a1,…,an−1a0,a1,…,an−1 into a power sequence.
Input
The first line contains an integer nn (3≤n≤1053≤n≤105).
The second line contains nn integers a0,a1,…,an−1a0,a1,…,an−1 (1≤ai≤1091≤ai≤109).
Output
Print the minimum cost to transform a0,a1,…,an−1a0,a1,…,an−1 into a power sequence.
思路:
- 首先:升序重排一定是最优的,因为最终的Power Sequence 升序,因此我们升序排列一定最贴合最终序列。
对于 q , n q,n q,n,假设 q = 10 , n = 100 q=10,n=100 q=10,n=100,最后一项就是 q = 1 0 100 q=10^{100} q=10100,非常之大,明显不符合题意,因此引发我们思考,去寻找 q q q的取值范围。
下面简单证明一下 q q q的取值范围
对于长度为n的序列 [ a 1 . . . . . a i ] [a_1.....a_i] [a1.....ai],最起码的我们可以让其全部变为1满足Power Sequence,让其全变为的花费为 s u m = ∑ i = 1 n ( a i − 1 ) sum=\sum_{i=1}^{n}(a_i-1) sum=∑i=1n(ai−1)
,现在来确定一下sum的取值范围,当
a
i
=
1
0
9
a_i=10^9
ai=109,
s
u
m
sum
sum为最大花费,即
s
u
m
<
n
∗
1
0
9
sum<n*10^9
sum<n∗109。最终形成的Power Sequence,公比
q
=
c
q=c
q=c,其第
n
n
n项为最大值
a
n
=
q
n
−
1
a_n=q^{n-1}
an=qn−1,如果
a
n
>
s
u
m
a_n>sum
an>sum那么就毫无意义,因此需要满足
a
n
<
=
s
u
m
an<=sum
an<=sum,即
q
n
−
1
<
=
s
u
m
<
n
∗
1
0
9
q^{n-1}<=sum<n*10^9
qn−1<=sum<n∗109,化简一下就可以得到q的取值范围
1
<
=
q
<
n
∗
1
0
9
n
−
1
1<=q<\sqrt[n-1]{n*10^9}
1<=q<n−1n∗109
我们枚举q难道会超时吗?其实不然,我们时间复杂度为
O
(
n
∗
q
)
=
O
(
n
∗
n
∗
1
0
9
n
−
1
)
O(n*q)=O(n*\sqrt[n-1]{n*10^9})
O(n∗q)=O(n∗n−1n∗109),n=3的时候
我们发现n最小值为3,即
1
<
=
q
<
n
∗
1
0
9
n
−
1
<
=
3
∗
1
0
9
<
1
0
5
1<=q<\sqrt[n-1]{n*10^9}<=\sqrt{3*10^9}<10^5
1<=q<n−1n∗109<=3∗109<105
n=4的时候
q
<
1
e
4
q<1e4
q<1e4,很明显递减了(也可以对公式求导进行直接验证),因此我们时间上限为
3
∗
1
0
9
<
1
0
5
\sqrt{3*10^9}<10^5
3∗109<105
综上:不会超时
算法
枚举n和q算出即可,唯一注意的是
1
<
=
q
<
n
∗
1
0
9
n
−
1
<
=
3
∗
1
0
9
<
1
0
5
1<=q<\sqrt[n-1]{n*10^9}<=\sqrt{3*10^9}<10^5
1<=q<n−1n∗109<=3∗109<105
后面式子c++会自动向下取整,因此等式修改为
1
<
q
<
=
[
n
∗
1
0
9
n
−
1
]
<
=
[
3
∗
1
0
9
]
<
1
0
5
1<q<=[\sqrt[n-1]{n*10^9}]<=[\sqrt{3*10^9}]<10^5
1<q<=[n−1n∗109]<=[3∗109]<105
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int r[N];
int main() {
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>r[i];
}
sort(r,r+n);
ll res=LLONG_MAX;
ll up=pow(1e9*n,1.0/(n-1)); //最大值
for(ll q=1;q<=up;q++){
ll x=1,sum=0;
for(int i=0;i<n;i++){
sum+=abs(r[i]-x);
x*=q;
}
res=min(res,sum);
}
cout<<res<<endl;
}