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 */
  • 相关阅读:
    uva 147 Dollars
    hdu 2069 Coin Change(完全背包)
    hdu 1708 Fibonacci String
    hdu 1568 Fibonacci
    hdu 1316 How Many Fibs?
    poj 1958 Strange Towers of Hanoi
    poj 3601Tower of Hanoi
    poj 3572 Hanoi Tower
    poj 1920 Towers of Hanoi
    筛选法——素数打表
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9006887.html
Copyright © 2011-2022 走看看