zoukankan      html  css  js  c++  java
  • 洛谷P3620 [APIO/CTSC 2007]数据备份 学习笔记

    反悔贪心,思维量非常大,重点如下:

    1.d[i]存区间,表示i-i+1的长度。

    2.二叉堆来维护最小值

    3.每次只有两种可能,一种是取不相邻的边,另一种是取相邻的边,如果取相邻的边,那么必定是破坏之间的集合重组,在代码上显示的就是差值

    4.合边操作并不是真的合边,而是差值刚好就能代表重组集合,在数学意义上相等,但是在物理意义上不等。

    #include <iostream>
    #include <set>
    #include<queue>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> pll;
    const int N = 100010;
    int n, k;
    int l[N], r[N];
    LL d[N];
    int vis[N];
    void delete_node(int p){
        r[l[p]] = r[p];
        l[r[p]] = l[p];
    }
    priority_queue<pll,vector<pll>,greater<pll> > q;
    int main(){
        cin >> n >> k;
    
        for (int i = 0; i < n; i ++ ) 
        cin >> d[i];
        for (int i = n - 1; i; i -- ) d[i] -= d[i - 1];
    
        d[0] = d[n] = 1e15;
        for (int i = 0; i <= n; i ++ ){
            l[i] = i - 1;
            r[i] = i + 1;
            q.push({d[i],i});
        }
    
        LL res = 0;
        while (k -- ){
            while(vis[q.top().second])
            q.pop();
            pll t=q.top();
            q.pop();
            int p = t.second, 
            left = l[p], right = r[p];
            vis[l[p]]=vis[r[p]]=1;
            delete_node(left), delete_node(right);
            res +=t.first;
            d[p] = d[left] + d[right] - d[p];
            q.push({d[p],p});
        }
    
        cout << res << endl;
    
        return 0;
    }
    View Code
  • 相关阅读:
    【转】ArcGIS 合并要素 Union Dissolve Append Merge
    Linux命令行下编辑常用快捷键
    rpm aid用法
    SUSE 吉祥物图片
    F9初装体验
    openSUSE10、SUSE EVAL10和SUSE10的区别[翻译]
    装有Linux DIY牛人百元人民币昂贵甜头液晶一体机
    SUSE10.3恢复GRUB体例
    64位Fedora还挑CPU
    Ubuntu8.04安置XCrysDen
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12238631.html
Copyright © 2011-2022 走看看