(DP) bzoj 2298
2298: [HAOI2011]problem a
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 714 Solved: 314
[Submit][Status][Discuss]
Description
一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)
Input
第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、bi
Output
一个整数,表示最少有几个人说谎
Sample Input
3
2 0
0 2
2 2
2 0
0 2
2 2
Sample Output
1
HINT
100%的数据满足: 1≤n≤100000 0≤ai、bi≤n
转化成线段区间形式 就好了,逆向思维,求最多说实话的人
dp[i]=max(dp[i],dp[前人]+该区间上的人数)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<string> #include<map> #include<vector> using namespace std; map< pair<int ,int>, int > mp; vector<int> e[100005]; int n,dp[100005]; int main() { int a,b,x,y; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&a,&b); x=a+1,y=n-b; if(x>y) continue; mp[make_pair(x,y)]++; if(mp[make_pair(x,y)]==1) e[y].push_back(x); } for(int i=1;i<=n;i++) { dp[i]=dp[i-1]; for(int j=0;j<e[i].size();j++) { dp[i]=max(dp[i],dp[e[i][j]-1]+min(mp[make_pair(e[i][j],i)],i-e[i][j]+1)); } } printf("%d\n",n-dp[n]); return 0; }