Problem E. Tenzing and Triangle
只要能写出暴力 dp 就成功了 90% 啦!
不妨先把所有点都加起来,考虑最优能通过覆盖节省多少。我们发现一个有用的性质是,三角形覆盖的区域,是不需要重叠的,因此似乎可以简单的 1D/1D 动态规划。
这里我们用树状数组,可以维护出三角形覆盖区域的代价。
#include <lastweapon/io>
#include <lastweapon/fenwicktree>
using namespace lastweapon;
const int N = int(2e5) + 9;
int n, k, A; vector<PII> P[N]; LL f[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n,k,A); LL z = 0;
REP(i ,n) {
int x, y, c; RD(x, y, c);
z += c; P[k-x].PB({y, c});
}
fenwick_tree<int> T(k+1);
REP(i, k+1) {
for (auto p: P[i]) T.add(p.fi, p.se);
checkMax(f[i], (LL)T.sum(0, i+1) - A*i);
REP(j, i) checkMax(f[i], f[j] + T.sum(j+1, i+1) - A*(i-j-1));
}
cout << z - f[k] << endl;
}
进一步的我们再把这个转移分离分离放到线段树里求 rmq 就好了。
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(2e5) + 9;
const int NN = 4*N;
int n, k, A; vector<PII> P[N]; int f[N];
struct SegTree {
#define lx (x<<1)
#define rx (lx|1)
#define ml ((l+r)>>1)
#define mr (ml+1)
#define lc lx,l,ml
#define rc rx,mr,r
#define rt 1,0,k
int T[NN], D[NN];
void add(int x, int d) {
D[x] += d;
T[x] += d;
}
void rls(int x) {
//return;
if (D[x]) {
add(lx, D[x]);
add(rx, D[x]);
D[x] = 0;
}
}
void upd(int x) {
T[x] = max(T[lx], T[rx]);
}
void Build(int x, int l, int r) {
if (l == r) {
T[x] = A*l;
} else {
Build(lc);
Build(rc);
upd(x);
}
}
int Add(int x, int l, int r, const int p, const int d) {
if (l == r) {
T[x] += d;
} else {
rls(x);
if (p < mr) Add(lc, p, d);
else Add(rc, p, d);
upd(x);
}
}
void Add(int x, int l, int r, const int a, const int b, const int d) {
if (b < l || r < a) return;
if (a <= l && r <= b) {
add(x, d);
} else {
rls(x);
Add(lc, a, b, d);
Add(rc, a, b, d);
upd(x);
}
}
int Query(int x, int l, int r, const int a, const int b) {
if (b < l || r < a) return 0;
if (a <= l && r <= b) {
return T[x];
} else {
rls(x);
return max(Query(lc, a, b), Query(rc, a, b));
}
}
} T;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n,k,A); int z = 0; REP(i, n) {
int x, y, c; RD(x, y, c); z += c;
P[k-x].PB({y, c});
}
T.Build(rt);
REP(i, k+1) {
if (i) T.Add(rt, i, f[i-1]);
for (auto p: P[i]) T.Add(rt, 0, p.fi, p.se);
checkMax(f[i], T.Query(rt, 0, i) - A*i);
}
cout << z - f[k] << endl;
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
