【Educational Codeforces Round 97 (Rated for Div. 2) C】Chef Monocarp
题目链接
翻译
给每道菜确定一个取出时间,每道菜对不愉快程度的贡献为它取出的时间和最佳取出时间差的绝对值。
要求最后不愉快程度之和最小,求这个最小值。
题解
动态规划,一个很显然的贪心是,我们把 \(t\) 进行排序,然后依次从小到大地顺序分配每个菜是最好的。
也即时间小的菜分配对应的时刻也应该要靠前。
最后用到的时刻一定不会超过 \(2*n\)。所以定义 \(f[i][j]\) 表示前 \(i\) 道菜已经分配完 \(1..j\)(不一定全用了) 这些时刻的最小
不愉快值,则有:
\(f[i][j] = min(f[i][j-1],f[i-1][j-1]+|j-t_i|)\)
代码
#include <bits/stdc++.h>
#define lson l,mid,rt*2
#define rson mid+1,r,rt*2+1
#define LL long long
using namespace std;
const int N = 200;
int t[N + 10],f[N + 10][2*N + 10],n;
int main(){
// freopen("C://1.cppSourceProgram//rush.txt","r",stdin);
ios::sync_with_stdio(0),cin.tie(0);
int T;
cin >> T;
while (T--){
cin >> n;
for (int i = 1;i <= n; i++){
cin >> t[i];
}
sort(t+1,t+1+n);
for (int i = 1;i <= n; i++){
for (int j = i;j <= 2*n; j++){
f[i][j] = f[i-1][j-1]+abs(j-t[i]);
if (j > i){
f[i][j] = min(f[i][j],f[i][j-1]);
}
}
}
cout << f[n][2*n] << endl;
}
return 0;
}