2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple

CRB and Apple

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 421    Accepted Submission(s): 131

Problem Description

In Codeland there are many apple trees.
One day CRB and his girlfriend decided to eat all apples of one tree.
Each apple on the tree has height and deliciousness.
They decided to gather all apples from top to bottom, so an apple can be gathered only when it has equal or less height than one just gathered before.
When an apple is gathered, they do one of the following actions.
1. CRB eats the apple.
2. His girlfriend eats the apple.
3. Throw the apple away.
CRB(or his girlfriend) can eat the apple only when it has equal or greater deliciousness than one he(she) just ate before.
CRB wants to know the maximum total number of apples they can eat.
Can you help him?

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains a single integer N denoting the number of apples in a tree.
Then N lines follow, i-th of them contains two integers Hi and Di indicating the height and deliciousness of i-th apple.
1 ≤ T ≤ 48
1 ≤ N ≤ 1000
1 ≤ Hi, Di ≤ 109

Output
For each test case, output the maximum total number of apples they can eat.

Sample Input
1
5
1 1
2 3
3 2
4 3
5 1

Sample Output
4

Author
KUT(DPRK)

Source

2015 Multi-University Training Contest 10

解题:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2010;
 4 int n,c[maxn][maxn],Li[maxn],tot;
 5 void add(int *T,int i,int val){
 6     while(i <= tot){
 7         T[i] = max(T[i],val);
 8         i += i&-i;
 9     }
10 }
11 int query(int *T,int i,int ret = 0){
12     while(i > 0){
13         ret = max(ret,T[i]);
14         i -= i&-i;
15     }
16     return ret;
17 }
18 struct Apple{
19     int h,d;
20     bool operator<(const Apple &rhs)const{
21         if(h == rhs.h) return d > rhs.d;
22         return h < rhs.h;
23     }
24 }A[maxn];
25 int main(){
26     int kase;
27     scanf("%d",&kase);
28     while(kase--){
29         scanf("%d",&n);
30         memset(c,0,sizeof c);
31         for(int i = 0; i < n; ++i){
32             scanf("%d%d",&A[i].h,&A[i].d);
33             Li[tot++] = A[i].d;
34         }
35         sort(Li,Li + tot);
36         tot = unique(Li,Li + tot) - Li;
37         sort(A,A+n);
38         for(int i = 0; i < n; ++i)
39          A[i].d = tot - (lower_bound(Li,Li + tot,A[i].d)-Li);
40         for(int i = 0; i < n; ++i){
41             memset(Li,0,sizeof Li);
42             for(int j = 1; j <= tot; ++j)
43                 Li[j] = query(c[j],A[i].d) +1;
44             for(int j = 1; j <= tot; ++j){
45                 add(c[j],A[i].d,Li[j]);
46                 add(c[A[i].d],j,Li[j]);
47             }
48         }
49         int ret = 0;
50         for(int i = 1; i <= tot; ++i)
51             ret = max(ret,query(c[i],tot));
52         printf("%d\n",ret);
53     }
54     return 0;
55 }

时间: 2024-08-26 21:25:42

2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple的相关文章

2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(递推+单线约瑟夫问题)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 题目大意:给你n个人排成一列编号,每次杀第一个人第i×k+1个人一直杀到没的杀.然后剩下的人重新编号从1-剩余的人数.按照上面的方式杀.问第几次杀的是谁. 分析 一轮过后和原来问题比只是人的编号发生变化,故可以转化为子问题求解,不妨设这n个人的编号是0~n-1,对于第i个人,如果i%k=0,那么这个人一定是第一轮出列的第i/k+1个人:如果i%k!=0,那么这个人下一轮的编号就是i

2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)

HDU 5861 题意 在n个村庄之间存在n-1段路,令某段路开放一天需要交纳wi的费用,但是每段路只能开放一次,一旦关闭将不再开放.现在给你接下来m天内的计划,在第i天,需要对村庄ai到村庄bi的道路进行开放.在满足m天内花费最小的情况下,求出每天的花销. 分析: 我们可以想到用线段树想到记录每一段路的开始时间与结束时间,开始时间很简单,就是一开始的时间,结束的时间求法可以参考区间覆盖,这是类似的: 然后我们在转化哪一天开哪些,哪一天关哪些,那这天的贡献sum = 开-关 ; 这很关键,我在比

【费用流】HDU 5406 CRB and Apple

通道 题意: 思路: 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; typedef long long ll; template <class T> inline bool rd(T &ret) { char c; int sgn; if(c = getchar() , c == EOF

HDU 5406 CRB and Apple 花样费用流向解法

题意简化一下就是一个序列,找出两个最大不下降子序列使得他们的长度和最长. = =作为一个DP渣,状态设计大概也就到了dp[i][j]表示第一个人最后一次取到i,第二个人取到j这个地方了..怎么在可行复杂度内转移?不会啊望天.. 其实作为图论工作者第一反应是费用流,但是边数太多了没敢搞= = 然而其实费用流也是可以过的.(x, y)表示容量为x费用为y, 建图很简单,建源s和汇e,加一个点t限制从 源最多流量是2,也就是s->t(2, 0).将各个点拆掉限制只能取一次,x->x'(1, 1),容

2015 Multi-University Training Contest 2 hdu 5303 Delicious Apples

Delicious Apples Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1057    Accepted Submission(s): 354 Problem Description There are n apple trees planted along a cyclic road, which is L metres

HDU5406---CRB and Apple( DP) 2015 Multi-University Training Contest 10

题意比较简单, dp[i][j] 表示上一次男女吃的deliciousness分别为i, j的时候的吃的最多的苹果. 那么dp[i][j] = max(dp[i][k] + 1),   0 <  k <= j dp[i][j] = max( max(dp[k][j]) + 1 ) , 0 < k <= i 对于第一个式子最大值 用树状数组线段树都可以解决, 第二个式子如果每次从0遍历到i再找最值的话,显然会超时. 仔细想想便可以发现第二个最值和第一个是一样的. 这个不好解释. 像是

[dfs] HDU 2019 Multi-University Training Contest 10 - Block Breaker

Block Breaker Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Given a rectangle frame of size n×m. Initially, the frame is strewn with n×m sq

2018 Multi-University Training Contest 3 - HDU Contest

题解: solution Code: A. Ascending Rating #include<cstdio> const int N=10000010; int T,n,m,k,P,Q,R,MOD,i,a[N],q[N],h,t;long long A,B; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d%d%d%d%d",&n,&m,&k,&P,&am

2018 Multi-University Training Contest 10

Rank Solved A B C D E F G H I J K L 67/761 6/12 . . . . O . O O O O . O O: 当场通过 ?: 赛后通过 .: 尚未通过 A Alkane unsolved B Beads unsolved C Calculate unsolved D Permutation unsolved E TeaTree solved by chelly chelly's solution F NewNippori unsolved G Cyclic