题意:给定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