zoj3381 Osaisen Choudai!
生活随笔
收集整理的這篇文章主要介紹了
zoj3381 Osaisen Choudai!
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:忽略題目背景,就是要收集最多的錢, 如果第i天拿到了si 的錢, 那么第i+x[i] 天 到 第i + y[i] - 1 天必須再拿一次,否則就再也拿不到錢了,當(dāng)然,第i +x[i]天之前也是拿不到的, 題目要求第一天必須拿。。
分析:一開始想到了用記憶化搜索,代碼很短, 一下就敲完了, 結(jié)果也果斷超時了
后來想到了按記憶化搜索的思路,直接從最后一天開始算起,用dp[i] 表示第i天拿到了錢之后,到第n天為止,最多拿到的錢數(shù),
?那么dp[i] = s[i] + max(dp[j]) ? ?(i + x[i] <= j <= i + y[i] - 1)
到這一步就很明顯了,這里涉及到了區(qū)間最值的問題,我們可以用線段樹來維護(hù)
?
zoj3381 #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<stdlib.h>using namespace std;const int N = 50000 + 10;int dp[N]; int s[N], x[N], y[N]; int n;struct node {int l, r, maxx; }p[N * 3];void build(int s, int t, int k) {p[k].l = s, p[k].r = t;p[k].maxx = 0;if( s == t )return ;int kl = k << 1, kr = kl + 1, mid = (s + t) >> 1;build(s, mid, kl);build(mid + 1, t, kr); }void update(int k, int s, int val) {if(s == p[k].l && p[k].r == p[k].l){p[k].maxx = val;return ;}int kl = k << 1, kr = kl + 1, mid = (p[k].l + p[k].r) >> 1;if( s <= mid ) update(kl, s, val);else update(kr, s, val);p[k].maxx = max(p[kl].maxx, p[kr].maxx); }int query(int s, int t, int k) {if( s <= p[k].l && t >= p[k].r){return p[k].maxx;}int mid = (p[k].l + p[k].r) >> 1;int kl = k << 1, kr = kl + 1;int a = 0, b = 0;if(s <= mid) a = query(s, t, kl);if(t > mid) b = query(s, t, kr);return max(a, b); }int main() {while(scanf("%d",&n) == 1){for(int i = 1; i <= n; ++i)scanf("%d %d %d",&s[i], &x[i], &y[i]);build(1, n, 1);update(1, n, s[n]);int ans = 0;for(int i = n - 1; i >= 1; --i){int l = i + x[i];int r = i + y[i] - 1;r = min(r, n);int val = s[i] + query(l, r, 1);update(1, i, val);if(i == 1) ans = val;}printf("%d\n",ans);}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/nanke/archive/2013/04/06/3002496.html
總結(jié)
以上是生活随笔為你收集整理的zoj3381 Osaisen Choudai!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Thumb 指令集
- 下一篇: java Io流实现图片复制