BZOJ2298 [HAOI2011]problem a

来源:互联网 发布:windows如何更新系统 编辑:程序博客网 时间:2024/05/16 14:12

挺厉害的题

答案就是n-最多有多少人同时说真话

考虑第i个人说的话,那么他的意思就是他的排名在a[i]+1到n-b[i]之间,且这个区间里的人分数都相等

那么我们考虑dp,f[i]表示i和i+1的分数不一样,考虑所有排名小于等于i的人最多有多少人说真话,那么我们枚举分数上一次改变在哪,进行转移即可

也就是枚举所有右端点是i的区间,用f[j-1]+min(区间长度,这个区间的数量)更新f[i]即可

#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 100010#define MAXM 1010#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000struct itv{int l;int r;itv(){}itv(int _l,int _r){l=_l;r=_r;}friend bool operator <(itv x,itv y){return x.r!=y.r?x.r<y.r:x.l<y.l;}};itv a[MAXN];int n,tot;int f[MAXN];int main(){int i,x,y;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d%d",&x,&y);if(x+y<n){a[++tot]=itv(x+1,n-y);}}sort(a+1,a+tot+1);int wzh=1;for(i=1;i<=n;i++){f[i]=f[i-1];int t=0;while(a[wzh].r<i){wzh++;}while(a[wzh].r==i&&wzh<=tot){if(a[wzh].r==a[wzh-1].r&&a[wzh].l==a[wzh-1].l){t++;}else{t=1;}f[i]=max(f[i],f[a[wzh].l-1]+min(t,a[wzh].r-a[wzh].l+1));wzh++;}}printf("%d\n",n-f[n]);return 0;}/**/


0 0
原创粉丝点击