P2519 [HAOI2011]problem a
Posted tidoblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2519 [HAOI2011]problem a相关的知识,希望对你有一定的参考价值。
题目描述
一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)
输入格式
第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、bi
输出格式
一个整数,表示最少有几个人说谎
输入输出样例
输入 #1
3 2 0 0 2 2 2
输出 #1
1
说明/提示
100%的数据满足: 1≤n≤100000 0≤ai、bi≤n
这是一个非常神奇的问题
首先 有ai个人分数比i高 有bi个人分数比i低
那么很显然能够看出来
ai+1 - n-bi 这一段区间里的人的分数都是一样的
那么也就是说问题就转化为了
有许多的区间 这些个区间里的人的分数都是一样的
然后来看一看最多能保证这里面的多少区间是合法的
用n减去那个值就是至少有多少个人说的是假的
首先我们是要先把区间排一个序
然后要去重 这个去重就是如果有两个区间起点终点完全一样 那么就直接删掉一个 把另一个的权值+1
据说这就成了一个区间dp(听起来好像我没有学过的样子)
转移方程据说是这个样子的f[i]=minf[i-1],f[L-1]+V
这个是什么意思呢
可以是直接继承i-1 就是什么也不干
也可以用当前枚举到的右端点为i的区间 f[L-1]不就是到当前区间的左端点为止的最大收益吗 再加上当前区间的权值即可
其实我也是晕乎乎的 多做点题练一练就好啦
https://www.luogu.org/problem/P2519
/* P2519 [HAOI2011]problem a 题目描述 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数) 输入格式 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、bi 输出格式 一个整数,表示最少有几个人说谎 输入输出样例 输入 #1复制 3 2 0 0 2 2 2 输出 #1复制 1 说明/提示 100%的数据满足: 1≤n≤100000 0≤ai、bi≤n */ /* #include<bits/stdc++.h> using namespace std; struct node int l,r;//左端点 右端点 arr[100005]; int f[100005]; map<node,int> mp_node;//存储权值+判重 bool cmp(node a,node b) if(a.r==b.r)return a.l<b.l; return a.r<b.r; int main() int n;scanf("%d",&n);int n_arr=0; for(int i=1;i<=n;i++) int a,b;scanf("%d%d",&a,&b); int L=a+1,R=n-b; node tmp;tmp.l=L;tmp.r=R; if(!mp_node[tmp]) arr[++n_arr].l=L,arr[n_arr].r=R; mp_node[tmp]++; sort(arr+1,arr+n_arr+1,cmp); int j=1; for(int i=1;i<=n;i++) f[i]=f[i-1]; while(j<=n_arr&&arr[j].r==i) f[i]=max(f[i],f[arr[j].l-1]+mp_node[arr[j]]); j++; printf("%d",n-f[n]); return 0; */ #include<bits/stdc++.h> #define maxn 100005 using namespace std; struct node int l,r; arr[maxn]; bool cmp(node a,node b) if(a.r==b.r) return a.l<b.l; return a.r<b.r; int L[maxn],R[maxn],V[maxn],f[maxn]; int main() int n;scanf("%d",&n); for(int i=1;i<=n;i++) int x,y;scanf("%d%d",&x,&y); if(x+y>=n) continue; arr[i].l=x+1;arr[i].r=n-y; sort(arr+1,arr+n+1,cmp); int tot=0; for(int i=1;i<=n;i++) if(arr[i].l!=arr[i-1].l||arr[i].r!=arr[i-1].r) tot++; L[tot]=arr[i].l;R[tot]=arr[i].r; V[tot]=min(V[tot]+1,arr[i].r-arr[i].l+1);//very important // V[tot]++; int j=1; for(int i=1;i<=n;i++) f[i]=f[i-1]; while(j<=tot&&R[j]==i) f[i]=max(f[i],f[L[j]-1]+V[j]); j++; printf("%d",n-f[n]); return 0;
以上是关于P2519 [HAOI2011]problem a的主要内容,如果未能解决你的问题,请参考以下文章