HDU 3607 线段树+DP
来源:互联网 发布:mac下载的系统在哪 编辑:程序博客网 时间:2024/06/06 10:41
这题最裸的方法因该是O(n2)的。dp[i]=max(dp[j])+gi(1<=j<i且hi>hj) 其中dp[i]代表的是前i下能拿的最多的钱。 但这个数据范围有点大,是10W 之多。 在hi > hj这个限制下,我们可以联想到,不就是找比hi小的高度中能获得的最多的钱的那个状态么,再由数据范围,容易联想到用线段树优化这个过程。那么就先把所有的高度都离散化,然后每次先进行查询,将比hi小的高度中钱最多的状态找出,更新当前状态,然后再插入树中。
/*ID: CUGB-wwjPROG:LANG: C++*/#include <iostream>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cmath>#include <ctime>#define INF 1111111111#define MAXN 111111#define MAXM 444444#define PI acos(-1.0)#define L(X) X<<1#define R(X) X<<1|1using namespace std;struct node{ int left, right, mid; int mx;}tree[4 * MAXN];int dp[MAXN];int h[MAXN], x[MAXN];void make_tree(int s, int e, int C){ tree[C].left = s; tree[C].right = e; tree[C].mid = (s + e) >> 1; tree[C].mx = 0; if(s == e) return; make_tree(s, tree[C].mid, L(C)); make_tree(tree[C].mid + 1, e, R(C));}void up(int C){ tree[C].mx = max(tree[L(C)].mx, tree[R(C)].mx);}void update(int p, int v, int C){ if(tree[C].left == tree[C].right) { tree[C].mx = max(tree[C].mx, v); return; } if(tree[C].mid >= p) update(p, v, L(C)); else update(p, v, R(C)); up(C);}int query(int s, int e, int C){ if(tree[C].left >= s && tree[C].right <= e) return tree[C].mx; int ret = 0; if(tree[C].mid >= s) ret = max(ret, query(s, e, L(C))); if(tree[C].mid < e) ret = max(ret, query(s, e, R(C))); return ret;}int cnt;int bin(int v){ int low = 1; int high = cnt; while(low <= high) { int mid = (low + high) >> 1; if(x[mid] == v) return mid; if(x[mid] > v) high = mid - 1; else low = mid + 1; } return -1;}int main(){ int n; while(scanf("%d", &n) != EOF) { for(int i = 1; i <= n; i++) { scanf("%d%d", &h[i], &dp[i]); x[i] = h[i]; } sort(x + 1, x + n + 1); cnt = unique(x + 1, x + n + 1) - x - 1; make_tree(1, cnt, 1); int ans = 0; for(int i = 1; i <= n; i++) { int pos = bin(h[i]); int val; if(pos == 1) val = 0; else val = query(1, pos - 1, 1); dp[i] += val; ans = max(dp[i], ans); update(pos, dp[i], 1); } printf("%d\n", ans); } return 0;}
- HDU 3607 线段树+DP
- HDU 3607 线段树+离散化+DP
- HDU 3698 DP+线段树
- HDU 3564 线段树+DP
- hdu 4521(dp+线段树)
- hdu 3016(线段树+dp)
- hdu 3016 dp+线段树
- HDU 3016 线段树+简单dp
- hdu 4117 AC自动机 + DP+线段树
- hdu 3016(线段树+dp)
- hdu 3016 Man Down 线段树+dp
- hdu 3016 Man Down (线段树 + dp)
- hdu 4521 线段树+DP
- 【HDU】3016 Man Down 线段树DP
- hdu-4991(dp+线段树)
- HDU 3016 线段树单点更新+DP
- hdu 4521(线段树优化dp)
- HDU 3564 线段树+简单DP
- Hive安装
- 在Oracle官网下载Informatica PowerCenter .
- Engish good phases
- 安装Informatica PowerCenter 8.1.1服务器端,配置License Key,Connect string和character data movement mode .
- ARM裸机程序研究 - S3C2440时钟初始化
- HDU 3607 线段树+DP
- Chap5:使用JNI技术实现java程序调用第三方dll(c/c++)文件的功能
- 深入浅出SharePoint—嵌入SQL认证设计
- Oracle数据类型
- 动态规划法和贪心算法
- 关于使用jquery取得页面中选中的checkbox的实现
- 嵌入式Linux概念学习笔记
- SIGPIPE信号
- inux 查看进程信息