[HAOI2011] 问题A

  我一开始的思路是最长上升序列......

  我真的没见过这种解题的方法......

  我以前从没用过pair......

  所以我蛮想知道官方题解是啥......

  这题按名次DP。

  s[pair[l,r]] 表示排名在 [l,r] 内的人数个数。

  f[i] 表示排名前 i 的最多的说真话的人数。

  对于 f[i] 的状态转移也是比较特别的,对于每一个确定的 r,只考虑从题目给出的数据 (l,r) 的 l 转移。

  对应程序是较好理解的,但是我真的不知道这思路咋来......

 

// q.c
// mark~

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int M=1000000+10;
vector<int> q[M];
map<pair<int,int>,int> s;
int f[M];
int main() {
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	int n,l,r;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%d%d",&l,&r);
		l++,r=n-r;
		if(l>r) continue;
		s[make_pair(l,r)]++;
		if(s[make_pair(l,r)]==1) q[r].push_back(l);
	}
	for(int i=1;i<=n;i++) {
		f[i]=f[i-1];
		for(int j=0,k=(int)q[i].size();j<k;j++) 
			f[i]=max(f[i],f[q[i][j]-1]+min(i-q[i][j]+1,s[make_pair(q[i][j],i)]));
	}
	printf("%d\n",n-f[n]);
	return 0;
}

 

posted @ 2018-04-15 15:11  qjs12  阅读(77)  评论(0编辑  收藏  举报