Chef Monocarp has just put n dishes into an oven. He knows that the i-th dish has its optimal cooking time equal to ti minutes.
At any positive integer minute T Monocarp can put no more than one dish out of the oven. If the i-th dish is put out at some minute T, then its unpleasant value is |T−ti| — the absolute difference between T and ti. Once the dish is out of the oven, it can’t go back in.
Monocarp should put all the dishes out of the oven. What is the minimum total unpleasant value Monocarp can obtain?
Input
The first line contains a single integer q (1≤q≤200) — the number of testcases.
Then q test cases follow.
The first line of the testcase contains a single integer n
(1≤n≤200) — the number of dishes in the oven.
The second line of the testcase contains n
integers t1,t2,…,tn (1≤ti≤n) — the optimal cooking time for each dish.
The sum of n over all q testcases doesn’t exceed 200
Output
Print a single integer for each testcase — the minimum total unpleasant value Monocarp can obtain when he puts out all the dishes out of the oven. Remember that Monocarp can only put the dishes out at positive integer minutes and no more than one dish at any minute.
Example
Input
6
6
4 2 4 4 5 2
7
7 7 7 7 7 7 7
1
1
5
5 1 2 4 3
4
1 4 4 4
21
21 8 1 4 1 5 21 1 8 21 11 21 11 3 12 8 19 15 9 11 13
Output
4
12
0
0
2
21
Note
In the first example Monocarp can put out the dishes at minutes 3,1,5,4,6,2. That way the total unpleasant value will be |4−3|+|2−1|+|4−5|+|4−4|+|6−5|+|2−2|=4.
In the second example Monocarp can put out the dishes at minutes 4,5,6,7,8,9,10.
In the third example Monocarp can put out the dish at minute 1.
In the fourth example Monocarp can put out the dishes at minutes 5,1,2,4,3.
In the fifth example Monocarp can put out the dishes at minutes 1,3,4,5.
题意:
有n个菜,每个菜的最佳出锅时间是a[i],如果这个菜在T时刻出锅,那么它花费T-a[i],求所有的菜出锅的最小花费。
思路:
dp[ i ] [ j ] 表示在 i 时刻出锅 j 个菜的花费
在任意的一个时刻,只有两种状态,拿菜或不拿菜
因此状态转移方程为
dp[ i ][ j ]=minn(dp[ i ][ j ],dp[ i-1 ][ j ],dp[ i-1 ][ j-1 ]+abs( i - a[ j ]));
(minn是自己写的求最小值的函数)
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int a[500],dp[500][500];
int inf=0x3f3f3f3f;
int minn(int x,int y,int z)
{
if(x<=y&&x<=z)
return x;
if(y<=x&&y<=z)
return y;
if(z<=x&&z<=y)
return z;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,i,j;
memset(dp,inf,sizeof(dp)); //不能清空为0 清空函数内的数值只能为0,1或 inf
dp[0][0]=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(i=1;i<=2*n;i++)
{
dp[i][0]=0;//拿0个菜的花费为0
for(j=1;j<=n;j++)
{
dp[i][j]=minn(dp[i][j],dp[i-1][j],dp[i-1][j-1]+abs(i-a[j]));
}
}
printf("%d\n",dp[2*n][n]);
}
return 0;
}
最优出锅策略
探讨了如何通过动态规划算法计算多个菜品的最佳出锅时间,以最小化总的等待时间损失。介绍了状态转移方程的设计思路及具体实现。
597

被折叠的 条评论
为什么被折叠?



