zoukankan      html  css  js  c++  java
  • bzoj 1150

    思路:写的时候感觉是贪心但是没有什么思路... 看了题解,原来有一个选了能反悔的贪心思路, 如果最优那么每个城市只能和旁边的相邻

    城市连边,所以问题变成了由n个数,不能取相邻的两个数,取k个最小是多少。 我们将这n个数放进优先队列里边贪心地取小的,取完最小

    的之后,把当前这个now和当前这个的左边l[now]和右边r[now]的删掉,再加入一个 a[l[now]] + a[r[now]] - a[now], 下次选到这个就表明反悔啦

    即选了两边那个,中间那个不选, 需要注意的是拿掉的是最左或者最右是不用插入新的值的, l, r需要用链表维护一下。

    以后贪心题要考虑能不能设计出一种能让它反悔的方式。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define fi first
     4 #define se second
     5 #define mk make_pair
     6 #define pii pair<int,int>
     7 #define piii pair<int, pair<int,int>>
     8 
     9 
    10 using namespace std;
    11 
    12 const int N=2e5+7;
    13 const int M=1e4+7;
    14 const int inf=0x3f3f3f3f;
    15 const LL INF=0x3f3f3f3f3f3f3f3f;
    16 const int mod=1e9 + 7;
    17 
    18 int n, k, tot, b[N], a[N * 4], l[N], r[N];
    19 bool in[N];
    20 int main() {
    21     scanf("%d%d", &n, &k);
    22     for(int i = 1; i <= n; i++)
    23         scanf("%d", &b[i]);
    24     for(int i = 2; i <= n; i++)
    25         a[++tot] = b[i] - b[i - 1];
    26 
    27     for(int i = 1; i <= tot; i++) {
    28         l[i] = i - 1;
    29         if(i != tot) r[i] = i + 1;
    30         else r[i] = 0;
    31     }
    32     LL ans = 0;
    33     priority_queue<pii, vector<pii>, greater<pii> > que;
    34     for(int i = 1; i <= tot; i++) {
    35         que.push(mk(a[i], i));
    36     }
    37     while(k) {
    38         pii now = que.top();
    39         que.pop();
    40         if(in[now.se] == true) continue;
    41         k--;
    42         ans += now.fi;
    43         pii u;
    44         if(l[now.se] != 0 && r[now.se] != 0)
    45             u = mk(0, ++tot);
    46         else u = mk(0, 0);
    47         u.fi = a[l[now.se]] + a[r[now.se]] - now.fi;
    48         a[u.se] = u.fi;
    49         in[now.se] = true;
    50         in[l[now.se]] = true;
    51         in[r[now.se]] = true;
    52         in[u.se] = true;
    53         int ll = l[l[now.se]], rr = r[r[now.se]];
    54         l[u.se] = ll;
    55         r[u.se] = rr;
    56         if(ll) r[ll] = u.se;
    57         if(rr) l[rr] = u.se;
    58         if(l[now.se] !=0 && r[now.se] != 0) que.push(u), in[u.se] = false;
    59     }
    60     printf("%lld
    ", ans);
    61     return 0;
    62 }
    63 /*64 */
  • 相关阅读:
    目标检测算法综述
    深度相机原理揭秘--双目立体视觉
    UnderScore.jsAPI记录
    JS基础一
    Angular.js学习范例及笔记
    AngularJS应用,常用数组知识点
    框架开发之——AngularJS+MVC+Routing开发步骤总结——5.14
    Node.JS开发环境准备
    常用的Oracle函数收集
    程序员的修炼之道——从小工到专家
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9006887.html
Copyright © 2011-2022 走看看