[LG P2519][BZOJ2298][HAOI2011]problem a
生活随笔
收集整理的這篇文章主要介紹了
[LG P2519][BZOJ2298][HAOI2011]problem a
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[LG P2519][BZOJ2298][HAOI2011]problem a
題目描述
一次考試共有n個人參加
第i個人說:"有ai個人分數比我高,bi個人分數比我低。"
問最少有幾個人沒有說真話(可能有相同的分數)
輸入輸出格式
輸入格式:
第一行一個整數n,接下來n行每行兩個整數,第i+1行的兩個整數分別代表ai、bi
輸出格式:
一個整數,表示最少有幾個人說謊
輸入輸出樣例
輸入樣例#1:?
3 2 0 0 2 2 2輸出樣例#1:?
1說明
1≤n≤100000 0≤ai、bi≤n
?
?
Solution
只要想到一點,此題就很簡單了:
有個人比我高,個人比我低,意味著個人與我相同分數!
也就是說排名為的人的分數相同。
?
其中有兩種必定為假的情況:
?
去除這些之后,就只剩下一堆合法的區間????讓你選擇,每個區間的價值為說這句話的人數(當然價值最大為區間長度),且需滿足任意兩個選取的區間沒有公共點。
于是問題變成了:選取最大價值和的不相交區間。
?
這時只需要按區間右端點排序,直接DP+二分答案求解答案即可(相信看懂題目和前面步驟的人都會這一步,另外,感覺這里的DP只是一個貪心而已。。。)。
#include<bits/stdc++.h> using namespace std; const int MAXN=1e5+500; int f[MAXN]; struct snode{int l,r;} score[MAXN]; struct qnode{int l,r,num; } q[MAXN]; int compare1(snode x,snode y){ return x.l<y.l||(x.l==y.l&&x.r<y.r); } int compare2(qnode x,qnode y){ return x.r<y.r||(x.r==y.r&&x.l<y.l); } inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } int find(int x,int n) {int l=0,r=n;while (l<r){int mid=(l+r+1)>>1;if (q[mid].r<x) l=mid;else r=mid-1;}return l; } int main() {int n=read(),cnt=0;for (int i=1;i<=n;i++) score[i].l=read()+1,score[i].r=n-read();sort(score+1,score+n+1,compare1);for (int i=1;i<=n;i++){if (score[i].l>score[i].r) continue;if (score[i].l==score[i-1].l&&score[i].r==score[i-1].r) q[cnt].num++;else q[++cnt]={(qnode){score[i].l,score[i].r,1}};}sort(q+1,q+cnt+1,compare2);for (int i=1;i<=cnt;i++){int k=find(q[i].l,cnt); f[i]=max(f[i-1],f[k]+min(q[i].num,q[i].r-q[i].l+1));}printf("%d\n",n-f[cnt]);return 0; }?
總結
以上是生活随笔為你收集整理的[LG P2519][BZOJ2298][HAOI2011]problem a的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 适合父亲节发朋友圈的文案 父亲节微信朋友
- 下一篇: 某谷 P1654 OSU!