CF1859C Another Permutation Problem 题解
乍一看正解似乎不好想,因此我们先将 \(O(2^n)\) 的爆搜写出来。
然后将 \(n \in [1,10]\) 都跑一遍,结果如下:
| \(n\) | \(p\) 数组 |
|---|---|
| \(1\) | \(0\) |
| \(2\) | \(2,1\) |
| \(3\) | \(1,3,2\) |
| \(4\) | \(1,2,4,3\) |
| \(5\) | \(1,2,5,4,3\) |
| \(6\) | \(1,2,3,6,5,4\) |
| \(7\) | \(1,2,3,4,7,6,5\) |
| \(8\) | \(1,2,3,4,8,7,6,5\) |
| \(9\) | \(1,2,3,4,5,9,8,7,6\) |
| \(10\) | \(1,2,3,4,5,6,10,9,8,7\) |
通过上表可以看出,最优解的排列 \(p\) 总是形如 \(1,2,3,\cdot\cdot\cdot,k,n,n-1,\cdot\cdot\cdot,k+1\)(\(0 \le k \le n\))。
于是我们枚举 \(k\) 的值,计算答案取最优解即可,时间复杂度 \(O(n^2)\)。
#include<bits/stdc++.h>
using namespace std;
int t,n,ans,a[310];
int calc(){
int res1=0,res2=-1e9;
for(int i=1;i<=n;i++) res1+=a[i]*i;
for(int i=1;i<=n;i++) res2=max(res2,a[i]*i);
return res1-res2;
}
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) a[i]=i;
ans=-1e9;
for(int k=0;k<=n;k++){
for(int j=1;j<=k;j++) a[j]=j;
int x=k;
for(int j=n;j>=k+1;j--) a[j]=++x;
ans=max(ans,calc());
}
cout<<ans<<'\n';
}
return 0;
}

浙公网安备 33010602011771号