hdu 5406CRB and Apple

//http://blog.csdn.net/keshuai19940722/article/details/47843837
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<stack>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
using namespace std;
typedef long long LL;
inline void fre1()
{
    freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);/*freopen("output.txt","w",stdout);*/
}
inline void fre2()
{
    fclose(stdin);/*fclose(stdout);*/
}
#define lowbit(x) (x&-x)//取x二进制数最小的1
#define MS(x,y) memset(x,y,sizeof(x))
#define maxn 1000+50
#define maxm 50000+50
#define INF (int)(1e8+7)
#define PI acos(-1)
#define EPS 1e-7
#define mod (LL)1e9+7
int idx[maxn],num;
int dp[maxn][maxn];//dp[i][j]表示第一个子序列最后一位为第二个子序列最后一位为j的最大值
struct treepoint
{
    int h,val;
    bool operator<(const treepoint&t)const
    {
        return h==t.h?val<t.val:h>t.h;
    }
} k[maxn];
void add(int x,int d,int *c)
{
    while(x<maxn)
    {
        c[x]=max(c[x],d);
        x+=lowbit(x);
    }
}
int get(int x,int *c)
{
    int ans=0;
    while(x>0)
    {
        ans=max(ans,c[x]);
        x-=lowbit(x);
    }
    return ans;
}
int solve()
{
    int n,i,j;
    scanf("%d",&n);
    for(i=1; i<=n; ++i)
    {
        scanf("%d%d",&k[i].h,&k[i].val);
        idx[i]=k[i].val;
    }
    sort(idx+1,idx+n+1);
    sort(k+1,k+n+1);
    num=1;
    for(i=2; i<=n; ++i)if(idx[i]!=idx[num])idx[++num]=idx[i];
    for(i=1; i<=n; ++i)
    {
        k[i].val=lower_bound(idx+1,idx+num+1,k[i].val)-idx;
    }
    //到这里为止是将书上的果子进行排序,并将美味值进行离散化

    int ans=0,tmp[maxn];
    MS(dp,0);
    for(i=1; i<=n; ++i)//枚举每一个k[i].val,每次其实把dp[1~n][1~n]都更新了
    {                  //dp[v][i]=dp[i][v]=max(dp[i][1~v])+1;
        int v=k[i].val;
        for(j=1; j<=n; ++j)
        {
            tmp[j]=get(v,dp[j])+1;//这里的get(v,dp[j])将相当于max(dp[i][1~v])
            ans=max(ans,tmp[j]);
        }
        for(j=1; j<=n; ++j)
        {
            add(v,tmp[j],dp[j]);//新的tmp[j]放到树状数组里对树状数组进行维护
            add(j,tmp[j],dp[v]);//这一步就是dp[v][i]=dp[i][v]
        }
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int ans=solve();
        printf("%d\n",ans);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值