[HAOI2011][BZOJ2298] problem a
2015-07-13 20:58
309 查看
2298: [HAOI2011]problem a
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 766 Solved: 346
[Submit][Status][Discuss]
Description
一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)Input
第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、biOutput
一个整数,表示最少有几个人说谎Sample Input
32 0
0 2
2 2
Sample Output
1HINT
100%的数据满足: 1≤n≤100000 0≤ai、bi≤n首先,要求最少说谎人数,即最大说真话人数。
对于每一个人,有a[i]个比他分数高的,b[i]个比他分数低的。则若序列为单调不增序列,和他同分的人的序号一定在a[i]+1->n-b[i]之间。因此可以想象成一段线段,问题转化为在一个长度为n的线段上有几段线段,求几段不想交的线段的长度之和,使这个值最大。
于是就是一个dp的题目了。方程显而易见。
又了解了一个map,在黄学长题解里还看到了动态数组?自己STL好弱……过几天系统学一下。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<map> using namespace std; map <pair<int,int>,int> s; int a,b,n,m,dp[100001],head[100001],next[100001],list[100001]; void add(int x,int y) { next[++m]=head[x]; head[x]=m; list[m]=y; } int main() { scanf("%d",&n); m=0; for (int i=1;i<=n;i++) { scanf("%d%d",&a,&b); if (a+b>=n) continue; a++; b=n-b; if (!s[make_pair(a,b)]) add(b,a); s[make_pair(a,b)]=min(s[make_pair(a,b)]+1,b-a+1); } for (int i=1;i<=n;i++) { dp[i]=dp[i-1]; for (int j=head[i];j;j=next[j]) { int u=list[j]-1; dp[i]=max(dp[i],dp[u]+s[make_pair(u+1,i)]); } } printf("%d",n-dp ); return 0; }
相关文章推荐
- Combination Sum
- 字体
- 史上最完整的省市县/区数据 三级联动数据库
- 每天小技(2015/07/13)
- 做安全一些基本原则
- 用户注册验证
- JQuery——日期拾取器
- IOS UI设计模式 - 分页
- Android 事件分发实践(一),解决ScrollView嵌套ListView滑动的问题
- 八大排序算法
- #笔记#圣思园 JavaWeb 第34讲——Session深度解析
- java Properties类的用法
- [NOIP2004] 合并果子
- eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能?
- 多类svm
- scikit-learn:2.5.矩阵因子分解问题
- Scala刮:使用Intellij IDEA写hello world
- CSS3常用形状
- Bestcoder Tom and matrix
- eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能?