zoukankan      html  css  js  c++  java
  • cf822C(贪心)

    题目链接: http://codeforces.com/problemset/problem/822/C

    题意: 有n条线段(n<=2e5) 每条线段有左端点li,右端点ri,价值cost(1 <= li <= ri <= 2e5, cost <= 1e9);

    对于一个给定的x(x <= 2e5),寻找两个不相交的线段,使它们的长度和恰好为x,并且价值和最小;

    思路: xjb贪心

    这题目肯定是枚举一条线段再找剩下一条线段, 假设枚举右线段, 且其长为len1, 那么我们需要找这条线段左边的长度为 x - len1 的线段的 cost 最小值;直接暴力的话是n^2的复杂度, 肯定 tle. 可以给这些线段按照左右端点排下序, 那么我们可以从按左端点排序的数组中枚举右线段, 然后在按右端点排序的数组中找左线段;但是如果暴力找的话时间复杂度还是 n^2 . 我们可以维护一个 vis数组, vis[i] 为当前右线段的左边线段中长度为 i 的 cost 最小值, 那么 vis[x - len1] 即为当前左线段的 cost 最小值;

    那么 cost1 + vis[x - len1] 的最小值即为答案啦;

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define ll long long
     6 using namespace std;
     7 
     8 const int MAXN = 2e5 + 10;
     9 const int inf = 0x7f7f7f7f;
    10 ll vis[MAXN];
    11 struct node{
    12     int l, r;
    13     ll w;
    14 }gel1[MAXN], gel2[MAXN];
    15 
    16 bool cmp1(node a, node b){
    17     return a.l < b.l;
    18 }
    19 
    20 bool cmp2(node a, node b){
    21     return a.r < b.r;
    22 }
    23 
    24 int main(void){
    25     int n, x;
    26     ll ans = inf;
    27     scanf("%d%d", &n, &x);
    28     for(int i = 0; i < n; i++){
    29         scanf("%d%d%lld", &gel1[i].l, &gel1[i].r, &gel1[i].w);
    30         gel2[i] = gel1[i];
    31     }
    32     sort(gel1, gel1 + n, cmp1);
    33     sort(gel2, gel2 + n, cmp2);
    34     memset(vis, 0x7f, sizeof(vis));
    35     int indx = 0;
    36     for(int i = 0; i < n; i++){
    37         ll gg = gel1[i].w;
    38         while(indx < n && gel2[indx].r < gel1[i].l){
    39             int cnt = gel2[indx].r - gel2[indx].l + 1;
    40             if(vis[cnt] > gel2[indx].w) vis[cnt] = gel2[indx].w;
    41             indx++;
    42         }
    43         int cc = x - (gel1[i].r - gel1[i].l + 1);
    44         if(cc <= 0) continue;
    45         gg += vis[cc];
    46         if(ans > gg) ans = gg;
    47     }
    48     if(ans == inf) cout << -1 << endl;
    49     else cout << ans << endl;
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    冒泡排序
    【代码审计】appcms 文件包含漏洞
    【知识学习】PHP实现批量替换字典后缀
    【代码学习】PYTHON 列表循环遍历及列表常见操作
    【代码学习】PYTHON字符串的常见操作
    【知识学习】Sublime Text 快捷键精华版
    【代码审计】变量覆盖漏洞详解
    【渗透测试】Msf提权步骤
    【代码审计】VAuditDemo 前台搜索功能反射型XSS
    【代码审计】VAuditDemo 前台搜索注入
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7116392.html
Copyright © 2011-2022 走看看