zoukankan      html  css  js  c++  java
  • P2519 [HAOI2011]problem a 题解

    Luogu

    Description.

    \(n\) 个人,第 \(i\) 个人说有 \(a_i\) 个人成绩比他高,有 \(b_i\) 个比他低。
    问至少几个人说谎了。

    Solution.

    首先考虑每个人说的话本质含义是什么。
    相当于对他来说,第 \(a_i+1\) 个人到第 \(n-b_i\) 人分数相同。
    我们分别设 \(l_i=a_i+1,r_i=n-b_i\),那也就是所有所选区间要么重合要么互不相连。
    然后一个区间最多只能被重合区间长度次。
    那么直接把重合区间压缩起来,做一个 dp 即可。

    Coding.

    点击查看颓怪代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),bz=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) bz=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	bz?x=-x:x;
    }/*}}}*/
    int n,m,F[100005],N;
    struct node{int l,r,v;}a[100005],b[100005];
    inline char cmp1(node x,node y) {return x.l^y.l?x.l<y.l:x.r<y.r;}
    inline char cmp2(node x,node y) {return x.r^y.r?x.r<y.r:x.l<y.l;}
    int main()
    {
    	read(N);for(int i=1;i<=N;i++) read(a[i].l),read(a[i].r),a[i].l++,a[i].r=N-a[i].r;
    	sort(a+1,a+N+1,cmp1);for(int i=1;i<=N;i++) if(a[i].l<=a[i].r) b[++m]=a[i];
    	for(int i=1;i<=m;i++)
    		if(i==1||b[i].l!=b[i-1].l||b[i].r!=b[i-1].r) a[++n]=b[i],a[n].v=1;
    		else if(a[n].v<a[n].r-a[n].l+1) a[n].v++;
    	sort(a+1,a+n+1,cmp2),F[1]=a[1].v;
    	for(int i=2;i<=n;i++)
    	{
    		int ls=upper_bound(a+1,a+i,(node){0,a[i].l},cmp2)-a-1;
    		F[i]=max(F[i-1],F[ls]+a[i].v);
    	}
    	return printf("%d\n",N-F[n]),0;
    }
    
  • 相关阅读:
    结对(求数组的最大子数组和)
    结对3(求一维数组最大子数组的和扩展)
    结对3(电梯调度需求分析)
    结对开发2(求二维数组的最大子数组和)
    四则运算3(四则运算2程序的扩展)
    四则运算2代码测试
    四则运算2程序及运行
    C++输出四则运算设计题的思路
    C++编程显示四则运算题目
    软件课外读物阅读计划
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15163793.html
Copyright © 2011-2022 走看看