zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接

    题目大意

      给你n组数,每组数有a和b两个数,代表数量和让数量加1的花费,问让所有数量都不相同的最小代价。

    解题思路

      如果直接贪心的话会发现情况很复杂。我们可以先求出所有数修改之后的数量应该是多少。如果两个数相同,那么其中一个数如果和其他数相同就得加到一个没有出现的数为止,不过有个更好的办法,对于这种情况,那么这几个数一定是连续的,所以可以先按a从小到大排序,如果之前的数字修改后,当前的数比他前一个数小,就让当前的数加1,设求出的数组为数组c。
      在得到数组c后,考虑如何用数组a转移到最后的数组b。设大于等于(a_i)(a_j)的最小的整数是(c_k),且(b_i>b_j),如果让(a_j)修改成(b_k),那么(a_i)就得修改成一个比x大的数,显然这样是不优的。所以需要优先使用b大的数字来修改。

    代码

    const int maxn = 2e5+10;
    const int maxm = 1e6+10;
    
    struct INFO {
    	int x, y;
    } info[maxn];
    int n, arr[maxn];
    int main() {
    	cin >> n;
    	for (int i = 1; i<=n; ++i) cin >> info[i].x, arr[i] = info[i].x;
    	for (int i = 1; i<=n; ++i) cin >> info[i].y;
    	sort(info+1, info+n+1, [](INFO a, INFO b) {return a.x<b.x;});
    	for (int i = 1; i<=n; ++i) arr[i] = max(arr[i-1]+1, info[i].x);
    	set<int> st;
    	for (int i = 1; i<=n; ++i) st.insert(arr[i]);
    	ll ans = 0;
    	sort(info+1, info+n+1, [](INFO a, INFO b) {return a.y>b.y;});
    	for (int i = 1; i<=n; ++i) {
    		auto it = st.lower_bound(info[i].x);
    		ans += 1LL*(*it-info[i].x)*info[i].y;
    		st.erase(it);
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    ubuntu shell插件
    通过更改服务器解决双系统ubuntu时间+8
    ubuntu安装mysql遇到的问题
    05 面向对象:构造方法&static&继承&方法 &final
    electron 大体结构
    js时间Date对象介绍及解决getTime转换为8点的问题
    Fiddler命令行和HTTP断点调试
    使用HTTP头去绕过WAF(bypasswaf)
    Linux下php5.3.3安装mcrypt扩展
    Error: Cannot find a valid baseurl for repo: epel
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14388106.html
Copyright © 2011-2022 走看看