您的位置:首页 > 产品设计 > UI/UE

2016 UESTC Training for Dynamic Programming L - 柱爷抢银行MkⅣ dp 线段树优化

2016-05-17 12:09 483 查看


L - 柱爷抢银行MkⅣ


Time Limit: 1000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)


Submit
Status

柱爷对金钱的掌控能力声名在外,连米达斯银行也想拉拢他当Entrepreneur。
但柱爷是个有原则的人。他发现了米达斯银行的阴谋,打算尽最大力量去破坏它,即从金融街的银行中回收尽可能多的钱。
金融街上有NN个银行。对于第ii间银行,它的坐标是xi,有vi的钱能被柱爷回收。因为金融街是与现实分离的异空间,可能会有很多间银行位
于同一坐标的不同时空内。
米达斯银行也不是咸鱼,他们规定了只能从较小号数的银行才能到达较大号数的银行。而且对于第ii间银行,只有从与坐标比它小yi以内的银行
才能到达它。即从满足以下条件的银行jj能到达银行ii,xi−yi≤xj≤xi,j<i

柱爷可以从任意一间银行开始抢钱,请问他最多能抢多少钱。


Input

第一行一个数N,即有N间银行。
之后有N行,每行3个数x

,vi,yi

数据保证:

1≤N≤105

1≤xi,vi,y
i≤109


Output

输出一个数,即柱爷最多能抢多少钱。


Sample input and output

Sample InputSample Output
3
1 2 1
3 1 1
2 2 3

4


Source

2016 UESTC Training for Dynamic Programming


My Solution

dp 线段树优化

dp[i] = max(dp[j]) + v[i] //

x[i] – y[i] <= x[j] < x[i]

首先按x[i]升序排序

用线段树优化时间,单点更新,区间查询

x[i],y[i]<=1e9,

需要离散化

max(dp[j]) = dpj = Query(l, r);

算出以后更新进去Modify(x, dp[i]);, 这样一次插入进去

当考虑dp[i]的时候里面必然是1 - i-1 是插入的,

因此满足只能从较小号数的银行才能到达较大号数的银行

复杂度 O(NLogN)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100000 + 8;
int xa[maxn], xb[maxn], nn, v[maxn], y[maxn];
//LL dp[maxn];

LL Top[4*maxn], Cover[4*maxn], dp[maxn];
int sz;   //size

LL _Query(int a, int b, int l, int r, int Ind)
{
if(a <= l && b >= r) return Top[Ind];
int mid = (l + r)>>1;
LL ret = Cover[Ind];
if(a <= mid) ret = max(ret, _Query(a, b, l, mid, Ind<<1));
if(b > mid) ret = max(ret, _Query(a, b, mid+1, r, (Ind<<1)+1));
return ret;
}

void _Modify(int a, int l, int r, int Ind, LL d)
{
if(l == r && l == a){
Cover[Ind] = Top[Ind] = d;
return;
}
int mid = (l + r)>>1;
if(a <= mid) _Modify(a, l, mid, Ind<<1, d);
else _Modify(a, mid+1, r, (Ind<<1)+1, d);
Top[Ind] = max(Top[Ind<<1], Top[(Ind<<1)+1]);
}

inline LL Query(int a, int b) {return _Query(a, b, 1, sz, 1);}
inline void Modify(int a, LL d) {return _Modify(a, 1, sz, 1, d);}         //!WA2 这里Modify 的 d 没有改成 long long ……

int main()
{
#ifdef LOCAL
freopen("a.txt", "r", stdin);
#endif // LOCAL
int n, x, l, r;
long long dpj;  //dp[maxn] ==>> dp
scanf("%d", &n);sz = n;
for(int i = 0; i < n; i++){
scanf("%d%d%d", &xa[i], &v[i], &y[i]);
}

memcpy(xb, xa, sizeof xa);
sort(xa, xa + n);
nn = unique(xa, xa + n) - xa;

memset(Top, 0, sizeof Top);
memset(Cover, 0, sizeof Cover);
for(int i = 0; i < n; i++){                                            //!这里坐标统一为 1 ~ nn 了
x = lower_bound(xa, xa + nn, xb[i]) - xa + 1;
l = lower_bound(xa, xa + nn, xb[i] - y[i]) - xa + 1;
r = x;

dpj = Query(l, r);
dp[i] = dpj + v[i];                                                 //!如果x本来有值也不要紧,被加在dpi里了
Modify(x, dp[i]);
}
//!WA2, 因为dpi可能是分开的所以, ans = max(dp[i]);这个不是test2 的是另外的地方的把
LL ans = 0;                                                             //cout<<dp[0]<<endl;
for(int i = 0; i < n; i++) ans = max(ans, dp[i]);
printf("%lld", ans); //ans 不是 dp[n-1] ☺☺
return 0;
}


Thank you!

------from ProLights
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: