HDU3016マン・ダウン】
問題の意味:あるN水平平面における線の部分は、各セグメントは、高さが与えられ、そしてエネルギー左端位置(正または負)、最初の行に、エネルギーと現在のラインセグメント上の最高点100を有していますそしてその後、全ての可能な垂直降下(他のセグメント上に落ちる可能性があり、また地面に落ちることができる)のエネルギー、エネルギーセグメントを得るには、他のライン上に落ち、ゲームが終了した場合ラインからの左または右、秋に地面にゲームを続行します、および現在のエネルギーのスコア。しかし、いずれかの時点では、エネルギー<= 0は、ゲームを終了するために失敗したポジティブなエネルギー、でなければなりません。出力がない場合は地面に落ちた場合は、最大スコアが出力され、-1
私のアプローチはかなり独特であるこの質問(愚かな)
0 EDのライン側との間に接続され、(左右端部が落下セグメントに到達する)、各セグメントは、他の2つのセグメントを指します、地上セグメントに対して仮定さ見ることができる、エッジ長が到着線上にあってもよいですエネルギーは、これは、有向グラフのうち建てたという、ラインはSpfaが最長の道路への0の数が最も多いが、(DPでうまくこの問題を解決するため、実際に)答えが得走りました
上記セグメントが更新続くので、高さに応じて、最低から最高まで、下に覆うことができ、クエリ番号二つのセグメントを見つけることができる:各セグメントから得られるキーは、二つのセグメント約2滝に到達します。現在の行の高さに応じがソートされている、例えば、左端点5までの処理は、線分10の右端点はI、最初の線分ツリーは5,10クエリA、次いで間隔が5--10 iの値に変更されます
#include <bits/stdc++.h>
using namespace std;
inline void read (int &x) {
char ch = getchar(); int f = 0; x = 0;
while (!isdigit(ch)) {if (ch == '-') f = 1; ch = getchar();}
while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
if (f) x = -x;
}
const int N = 1E5 + 10;
int n, cnt, M, c[N << 2], d[N], to[N][2], vis[N];
struct e {
int h, l, r, val;
bool operator < (const e &x) const {return h < x.h;}
} a[N];
#define ls p << 1
#define rs p << 1 | 1
inline void push_down (int p) {
if (c[p]) c[ls] = c[rs] = c[p], c[p] = 0;
}
int update (int p, int l, int r, int ql, int qr, int val) {
if (ql <= l && qr >= r) {c[p] = val; return 0;}
push_down (p);
int mid (l + r >> 1);
if (ql <= mid) update (ls, l, mid, ql, qr, val);
if (qr > mid) update (rs, mid + 1, r, ql, qr, val);
}
int query (int p, int l, int r, int pos) {
if (l == r) return c[p];
push_down (p);
int mid (l + r >> 1);
return pos <= mid ? query (ls, l, mid, pos) : query (rs, mid + 1, r, pos);
}
inline void Spfa () {
queue <int> q;
memset (d, 0xcf, sizeof (d));
memset (vis, 0, sizeof (vis));
d[n] = 100 + a[n].val, vis[n] = 1, q.push (n);
while (!q.empty()) {
int u = q.front ();
vis[u] = 0, q.pop ();
for (int i = 0; i <= 1; ++i) {
int v = to[u][i];
if (d[u] + a[v].val > d[v] && d[u] + a[v].val > 0) {
d[v] = d[u] + a[v].val;
if (!vis[v]) q.push (v), vis[v] = 1;
}
}
}
}
int main() {
while (~scanf ("%d", &n)) {
cnt = M = 0;
memset (c, 0, sizeof (c));
for (int i = 1; i <= n; ++i)
read (a[i].h), read (a[i].l), read (a[i].r), read (a[i].val), M = max (M, a[i].r);
sort (a + 1, a + n + 1);
for (int i = 1; i <= n; ++i) {
int tl = query (1, 1, M, a[i].l), tr = query (1, 1, M, a[i].r);
to[i][0] = tl, to[i][1] = tr;
update (1, 1, M, a[i].l, a[i].r, i);
}
Spfa ();
if (d[0] < 0) puts ("-1");
else printf ("%d\n", d[0]);
}
return 0;
}