C. Chef Monocarp

题意:给定n个盘子,每一个盘子有一个数字

   给定一个时间T,我们可以在每一分钟拿出一个盘子,权值为abs(拿出时刻-盘子权值)

   每一分钟只能拿一个盘子

   求,最小权值

思路:DP;

   我们开二维数组dp[][]

   前一维表示秒数,第二维表示枚举到了第J个盘子;

   我们计算的时候,要先将所有盘子权值按从小到大排序

   排完之后,跑一遍DP即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4  
 5 const int maxl=3e5+10;
 6 const int inf=2e9+10;
 7  
 8 int n,m,cnt,tot,cas,ans;
 9 int a[210],dp[1010][1010];
10 bool vis[maxl];
11 char s[maxl];
12  
13 inline void prework()
14 {
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++)
17         scanf("%d",&a[i]);
18     sort(a+1,a+1+n);
19 }
20  
21 inline void upd(int &x,int y){x=min(x,y);}
22  
23 inline void mainwork()
24 {
25     for(int i=0;i<=2*n;i++)
26         for(int j=0;j<=n;j++)
27             dp[i][j]=inf;
28     dp[0][0]=0;
29     for(int i=0;i<=2*n;i++)
30         for(int j=0;j<=n;j++)
31         if(dp[i][j]<inf){
32             upd(dp[i+1][j],dp[i][j]);
33             if(j+1<=n)
34                 upd(dp[i+1][j+1],dp[i][j]+abs(a[j+1]-(i+1)));   
35         }
36 }
37  
38 inline void print()
39 {
40     ans=inf;
41     for(int i=1;i<=2*n;i++)
42         ans=min(ans,dp[i][n]);
43     printf("%d\n",ans);
44 }
45  
46 int main()
47 {
48     int t=1;
49     scanf("%d",&t);
50     for(cas=1;cas<=t;cas++){
51         prework();
52         mainwork();
53         print();
54     }
55     return 0;
56 }
View Code

 

posted @ 2020-11-11 21:29  古比  阅读(133)  评论(0编辑  收藏  举报