您的位置:首页 > 其它

hdu 5406 2015 多校联合训练赛#10 dp

2015-08-24 08:44 507 查看


CRB and Apple

Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 358 Accepted Submission(s): 109



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

先对h排序,然后就只找两条不相交的最长不降子序列。

对d进行离散化。用dp[i][j]表示取到当前位置,两个子序列的最后一个苹果的可口值是i和j的情况下,

最多能吃的苹果个数。

对于当前的d,枚举i进行转移公式:dp[i][d] = dp[d][i] = dp[i][j] + 1 (j <= d)

根据不降子序列的性质有单调性,只需dp[i][d] = dp[d][i] = max(dp[i][j]), j<=d

用树状数组维护最大值即可

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
#define maxn 1001
int tree[maxn][maxn];
int m;
void add(int *T,int p,int n){
    for(;p<=m;p+=p&-p)
        T[p] = max(T[p],n);
}

int query(int *T,int p){
    int ans = 0;
    for(;p>0;p-=p&-p)
        ans = max(ans,T[p]);
    return ans;
}

struct Node{
    int h,d;
};
Node p[1001];
int comp(Node a,Node b){
    if(a.h == b.h) return a.d > b.d;
    return a.h < b.h;
}
int haha[maxn];
int main(){
    int t,n,h,d;
    //freopen("1001.in","r",stdin);
    //freopen("1001x.out","w",stdout);
    scanf("%d",&t);
    while(t--)
        memset(tree,0,sizeof(tree));
        scanf("%d",&n);
        for(int i = 0 ;i < n; i++){
            scanf("%d%d",&p[i].h,&p[i].d);
            haha[i] = p[i].d;
        }
        sort(haha,haha+n);
        m = unique(haha,haha+n)-haha;
        sort(p,p+n,comp);
        for(int i = 0;i < n; i++)
            p[i].d = m-(lower_bound(haha,haha+m,p[i].d)-haha);
        int d,u,v;
        for(int i = 0;i < n; i++){
            memset(haha,0,sizeof(haha));
            d = p[i].d;
            for(int j = 1;j <= m; j++)
                haha[j] = query(tree[j],d)+1;
            for(int j = 1;j <= m; j++){
                add(tree[j],d,haha[j]);
                add(tree[d],j,haha[j]);
            }
        }
        int ans = 0;
        for(int i = 1;i <= m; i++)
            ans = max(ans,query(tree[i],m));
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: