zoukankan      html  css  js  c++  java
  • 2298: [HAOI2011]problem a

    2298: [HAOI2011]problem a

    链接

    分析:

      每个人说的话,可以转化成区间[l,r]的人的排名是一样的,于是就转化成了区间带权覆盖问题。

      f[i]表示到第i个人,的最多有多少人说了真话,n-f[n]为答案。

      对于f[i],如果没有线段以i为右端点,f[i] = f[i-1]。

      如果有的话,那么这些线段可以选或不选,不选f[i]=f[i-1];选,它可以从最近的不想交的地方转移,找到此线段的左端点,然后f[i]=max(f[l]+min(w[l,i],i-l+1));w表示线段的权值,j-l+1,表示这条线段最大的价值。

      

      另一种写法:f[i]表示到第i条线段的最大价值,那么可以二分找到第一个不和这条线段相交的线段,从这里转移。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cctype>
     5 #include<map>
     6 #include<vector>
     7 #define mp(a,b) make_pair(a,b)
     8 #define pa pair<int,int>
     9 
    10 using namespace std;
    11 
    12 const int N = 100100;
    13 
    14 map < pa, int > w;
    15 vector < int > q[N];
    16 int f[N];
    17 
    18 inline int read() {
    19     int x = 0,f = 1;char ch=getchar();
    20     for (; !isdigit(ch); ch=getchar()) if(ch=='-')f=-1;
    21     for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
    22     return x*f;
    23 }
    24 int main() {
    25     int n = read();
    26     for (int i=1; i<=n; ++i) {
    27         int a = read(),b = read();
    28         int l = a + 1,r = n - b; // 注意! 
    29         if (l > r) continue;
    30         if (w[mp(l,r)] == 0) q[r].push_back(l);
    31         w[mp(l,r)] ++;
    32     }
    33     for (int r=1; r<=n; ++r) {
    34         f[r] = f[r-1]; // 不选 
    35         int sz = q[r].size();
    36         for (int i=0; i<sz; ++i) {
    37             int l = q[r][i];
    38             f[r] = max(f[r],f[l-1]+min(w[mp(l,r)],r-l+1)); //
    39         }
    40     }
    41     cout << n - f[n];
    42     return 0;
    43 }
  • 相关阅读:
    yum 下载安装包以及依赖包
    《将博客搬至CSDN》
    Lucene
    Solr
    LVS原理详解(3种工作模式及8种调度算法)
    正向代理与反向代理
    网关,网卡
    NAT地址转换
    Nginx学习总结
    网络_OSI模型_数据包传输
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9162109.html
Copyright © 2011-2022 走看看