思路
dp[i][j]
表示前i
秒选了j
个。容易得状态转移方程:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
−
1
]
[
j
−
1
]
+
a
b
s
(
a
[
j
]
−
i
)
)
dp[i][j]=min(dp[i-1][j],dp[i-1][j-1]+abs(a[j]-i))
dp[i][j]=min(dp[i−1][j],dp[i−1][j−1]+abs(a[j]−i))
再考虑
a
a
a数组为什么要排序,为了保证符合dp
的’性质’,不排序的话dp
是不对的。
#include<bits/stdc++.h>
using namespace std;
int a[210],dp[1010][210];
void solve(){
int n;cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=0;i<=n+n;++i){
for(int j=0;j<=n;++j){
dp[i][j]=1e9;
}
}
for(int i=0;i<=n+n;++i){
dp[i][0]=0;
}
for(int j=1;j<=n;++j){
for(int i=1;i<=n+n;++i){
dp[i][j]=min(dp[i-1][j],dp[i-1][j-1]+abs(a[j]-i));
}
}
int ans=1e9;
for(int i=1;i<=n+n;++i){
ans=min(ans,dp[i][n]);
}
cout<<ans<<endl;
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
}