2018 CCPC网络赛 1010 hdu 6447 ( 树状数组优化dp)

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

思路:很容易推得dp转移公式:dp[i][j] = max(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]+val[i][j]) ,但是很明显离散化后也无法储存这些点,我们可以用树状数组对这个状态转移公式进行优化,我们先以y轴为第一优先级从小到大排序,以x轴为第二优先级从大到小排序,对x轴坐标进行离散化,这样我们就只需要维护x轴上的最大值即可,状态转移方程可优化为: dp[i] = max(dp[i],dp[k]+val) 其中 0<k<i,dp[k]表示dp[1]到dp[i-1]的最大值(可用树状数组维护)

 

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 1e5+10;
struct node{
    int x,y,val;
    bool operator < (const node &k)const{
        if(y == k.y) return x > k.x;
        return y < k.y;
    }
}a[M];
int c[M],pos[M],n;
void add(int x,int val){
    while(x <= n){
        c[x] = max(c[x],val);
        x += (x&-x);
    }
}

int getsum(int x){
    int res = 0;
    while(x){
        res = max(res,c[x]);
        x -= (x&-x);
    }
    return res;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(c,0,sizeof(c));
        scanf("%d",&n);
        for(int i = 1;i <= n;i ++){
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].val);
            pos[i] = a[i].x;
        }
        sort(a+1,a+1+n); sort(pos+1,pos+1+n);
        int ans = 0;
        for(int i = 1;i <= n;i ++){
            int cnt = lower_bound(pos+1,pos+1+n,a[i].x)-pos;
            int num = a[i].val + getsum(cnt-1);
            ans = max(ans,num);
            add(cnt,num);
        }
        printf("%d\n",ans);
    }
}

 

posted @ 2018-08-29 13:05  冥想选手  阅读(190)  评论(0编辑  收藏  举报