zoukankan      html  css  js  c++  java
  • CodeVs 1615 数据备份

    题目:数据备份

    链接:Here

    题意:有n个点在一条线上,每次连线可以连接两个点(每个点只能被连一次),要求找出m个连线,他们的和最小(连线权值就是两点距离),输出最小的和。给出n、m和每个点的坐标。

    思路:

      可反悔贪心。

      容易得出连线必然是选择相邻的点组成,那么从连线权值最小的开始选(用优先队列实现),假设现在有6个连线(1、2、3、4、5、6),如果第一次选了3,但后面有可能发现w[3] + w[x](后面找到的一个满足条件的权值最小的连线)> w[2] + w[4](正常情况下选了3,就不可以选择2、4了),那么我可以反悔,重新选择2、4而抛弃3,要想做到这样,在把w[3]算入总和时,得把w[2]+w[4]-w[3]放入优先队列,以供日后反悔,基于假设,w[2]+w[4]-w[3]<w[x],那么先出来的就是w[2]+w[4]-w[3],此时sum+w[2]+w[4]-w[3]和最初选了2、4的结果一致,当然,在把w[2]+w[4]-w[3]算入总和时,得把这一块的左边连线w[1]与右边连线w[5]再结合,也就是w[1]+w[5]-(w[2]+w[4]-w[3]),放入优先队列,以供后面可以反悔。容易得到这个贪心是正确的。

    AC代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<math.h>
     5 #include<set>
     6 #include<map>
     7 #include<list>
     8 #include<stack>
     9 #include<queue>
    10 #include<vector>
    11 #include<string>
    12 #include<iostream>
    13 #include<algorithm>
    14 using namespace std;
    15 #define lson rt<<1
    16 #define rson rt<<1|1
    17 #define N 100010
    18 #define M 100010
    19 #define Mod 1000000007
    20 #define LL long long
    21 #define INF 1000000007
    22 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
    23 #define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
    24 #define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
    25 #define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
    26 #define MT(x,i) memset(x,i,sizeof(x))
    27 #define gcd(x,y) __gcd(x,y)
    28 const double PI = acos(-1);
    29 
    30 struct Node
    31 {
    32   int w,l,r,pos;
    33   bool friend operator < (Node a,Node b)
    34   {
    35     return a.w>b.w;
    36   }
    37 }w[N];
    38 
    39 bool vis[N];
    40 priority_queue<Node> q;
    41 
    42 int main()
    43 {
    44   int n,k;
    45   scanf("%d%d",&n,&k);{
    46     int pre = 0;
    47     FOR(i,1,n){
    48       scanf("%d",&w[i].w);
    49       int tmp = w[i].w;
    50       w[i].w -= pre;
    51       pre = tmp;
    52 
    53       w[i].pos = i;
    54       w[i].l = i-1;
    55       w[i].r = i+1;
    56     }
    57     w[2].l = w[n].r = 0;
    58 
    59     //while(q.size()) q.pop();
    60     FOR(i,2,n){
    61       q.push(w[i]);
    62     }
    63     int sum = 0;
    64     FOR(i,1,k){
    65       Node tmp;
    66       while(q.size()){
    67         tmp = q.top();
    68         q.pop();
    69         if(tmp.w == w[tmp.pos].w) break;
    70       }
    71       //printf("%d %d %d %d
    ",tmp.l,tmp.r,tmp.pos,tmp.w);
    72       tmp = w[tmp.pos];
    73       sum += tmp.w;
    74       Node now;
    75       now.pos = tmp.pos;
    76       now.l = w[tmp.l].l;
    77       now.r = w[tmp.r].r;
    78       w[now.l].r=now.pos;
    79       w[now.r].l=now.pos;
    80 
    81       if(tmp.l==0 || tmp.r==0) now.w=INF;
    82       else now.w = w[tmp.l].w + w[tmp.r].w - tmp.w;
    83       w[now.pos]=now;
    84 
    85       //printf("===%d %d %d %d
    ",now.l,now.r,now.pos,now.w);
    86       w[tmp.l].w = INF;
    87       w[tmp.r].w = INF;
    88       q.push(now);
    89     }
    90     printf("%d
    ",sum);
    91   }
    92   return 0;
    93 }
  • 相关阅读:
    腾讯云挂载文件服务器节点
    OpsManage 安装
    centos7 安装mysql
    vs code 新建vue项目
    Centos7 安装supervisor
    腾讯云Centos7 安装nginx
    django 生成pdf
    VM安装虚拟机
    ACM/ICPC 之 Floyd练习六道(ZOJ2027-POJ2253-POJ2472-POJ1125-POJ1603-POJ2607)
    ACM/ICPC 之 Floyd范例两道(POJ2570-POJ2263)
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/5922380.html
Copyright © 2011-2022 走看看