hdu 6447YJJ's Salesman 离散化+树状数组+DP

版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/Dale_zero/article/details/82055468

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447

因为图中点的坐标值过大,达到1e9.然而只有1e5个点。所以先将其离散化。并按照<x.y>二元组排序。每次对于同一行的点连续处理两次。

第一次:先考虑由上一行转移而来的情况:树状数组找到左上角的最大值+v、以及上方值的最大值。

第二次:考虑由同行的点转移来的情况。树状数组查询区间1~x-1的最大值

便利过程中维护最大值

代码丑的一批

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define mod 1000000007
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
#define sqr(a) a*a
using namespace std;

#define maxn 100010
int shu[maxn];

int lowbit(int i)
{
    return i&(-i);
}

int query(int i)
{
    int ans=0;
    while(i)
    {
        ans=max(ans,shu[i]);
        i-=lowbit(i);
    }
    return ans;
}

void update(int i,int p)
{
    while(i<=maxn-1)
    {
        shu[i]=max(p,shu[i]);
        i+=lowbit(i);
    }
}


struct node
{
    int x,y,v;
}a[100010];
int dp[100010];
int d[100010];

bool cmp(node a,node b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}

bool cmp1(node a,node b)
{
    if(a.y==b.y)
        return a.x<b.x;
    return a.y<b.y;
}


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        lan(d,0);
        lan(shu,0);
        lan(a,0);
        lan(dp,0);
        int n;
        scanf("%d",&n);
        int x,y,v;
        For(i,1,n)
        {
            scanf("%d%d%d",&x,&y,&v);
            a[i].x=x;
            a[i].y=y;
            a[i].v=v;
        }
        sort(a+1,a+1+n,cmp1);
        int tem=a[1].y;
        int id=1;
        a[1].y=1;
        For(i,2,n)
        {
            if(a[i].y==tem)
            {
                a[i].y=id;
            }
            else
            {
                tem=a[i].y;
                id++;
                a[i].y=id;
            }
        }
        sort(a+1,a+1+n,cmp);
        tem=a[1].x;
        id=1;
        a[1].x=1;
        d[1]=1;
        For(i,2,n)
        {
            if(a[i].x==tem)
            {
                a[i].x=id;
                d[id]++;
            }
            else
            {
                tem=a[i].x;
                id++;
                a[i].x=id;
                d[id]++;
            }
        }
        int maxx=0;
        id=0;
        int l=1,r;
        For(i,1,n)
        {
//            printf("d[%d]=%d\n",i,d[i]);
            if(!d[i])
                continue;
            For(j,1,d[i])
            {
               int k=j+id;
                x=a[k].x;
                y=a[k].y;
                v=a[k].v;
               int ans1=query(y-1)+v;
                int ans2=query(y);
//                printf("%d %d:%d %d\n",x,y,ans1,ans2);
                dp[y]=max(ans1,ans2);
            }
            For(j,1,d[i])
            {
                int k=j+id;
                    x=a[k].x;
                    y=a[k].y;
                    v=a[k].v;
//                    printf("%d %d:%d\n",x,y,query(y-1));
                    maxx=max(maxx,max(dp[y],query(y-1)));
                    update(y,max(dp[y],query(y-1)));
            }
                id+=d[i];
        }
        printf("%d\n",maxx);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dale_zero/article/details/82055468