http://www.codechef.com/download/translated/LTIME70/mandarin/PERMPART.pdf
Apparently only greater than or equal $ 2 * N $ number may be left
Suppose S_I $ $ $ i represents the number of occurrences in the original sequence $
It can be converted to the original problem: find such a sequence $ b $, satisfy $ \ sum_ {i = 1} ^ {2 * N} {| s_i-b_i |} $ is minimal, $ b $ does not rise
It is easy to think of $ n ^ 2 $ dynamic regulation
Provided $ dp_ {i, j} $ represents a minimum cost Before considering the number of $ I $, $ b_i = j $ first when
$ Dp_ {i, j} = min (dp_ {i-1, k}) + abs (s_i-j) $, where $ k \ geq j $, and then rolling the array optimization
The examination room thought so much
In fact, there is an obvious place: $ b_i \ leq \ frac {2 * N} {i} $
Such complexity is $ (nlog_2 {n}) O $
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,a[N],s[N<<1]; long long f[2][N<<1]; long long ans; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<=n<<1;++i) s[i]=0; ans=0; for(int i=1;i<=n;++i) { scanf("%d",&a[i]); if(a[i]>n<<1) ++ans; else ++s[a[i]]; } for(int i=1;i<=n<<1;++i) { long long minx=1e16; if(i>1) for(int j=(n<<1)/(i-1);j>(n<<1)/i;--j) minx=min(minx,f[(i-1)&1][j]); else minx=0; for(int j=(n<<1)/i;j>=0;--j) minx=min(minx,f[(i-1)&1][j]),f[i&1][j]=minx+abs(s[i]-j); } printf("%lld\n",ans+min(f[0][1],f[0][0])); } return 0; }