码迷,mamicode.com
首页 > 其他好文 > 详细

273. 分级

时间:2021-04-08 12:57:12      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:space   tps   排序   com   col   www   signed   出现   def   

题目链接:https://www.acwing.com/problem/content/275/

思路:首先要知道一个性质 : 一定存在一组最优解b[i] 使得每个b[i]都在a[i] 中出现过 证明略

然后考虑dp[i][j] 代表前i个a[i] 一定匹配好 且b中最后一个数是b[j]  的最小值 

可以知道 dp[i][j] =abs(a[i]-b[j]) 即当前这个贡献和 前面要最小的贡献  

前面最小的贡献  是 dp[i-1][k]  k=1~j 这样转移的话就需要三重循环  但是可以发现

可以用一个mi  边跑j循环的时候 边记录下dp[i-1][k] 的最小值 这样就是两重循环

单调递增只需要 升序排序即可  递减就 降序排序 dp即可

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e3+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,int>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 
12 int dp[maxn][maxn];
13 int a[maxn],b[maxn];
14 int n;
15 
16 int solve()
17 {
18     int ans=1e9;
19     for(int i=1;i<=n;i++)
20     {
21         int mi=1e9;
22         for(int j=1;j<=n;j++)
23         {
24             mi=min(mi,dp[i-1][j]);
25             dp[i][j]=mi+abs(a[i]-b[j]);
26         }
27     }
28     for(int i=1;i<=n;i++) ans=min(ans,dp[n][i]);
29     return ans;
30 }
31 
32 
33 int main()
34 {
35     ios::sync_with_stdio(false);
36     cin.tie(0);
37     cin>>n;
38     for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
39     sort(b+1,b+1+n);
40     int ans=1e9;
41     ans=solve();
42 
43 
44 
45     sort(b+1,b+1+n,greater<int>());
46     ans=min(ans,solve());
47 
48     cout<<ans<<\n;
49 
50 
51 
52 
53 }
View Code

 

273. 分级

标签:space   tps   排序   com   col   www   signed   出现   def   

原文地址:https://www.cnblogs.com/winfor/p/14623940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!