hdu 3016(线段树+dp)
2015-09-11 01:13
357 查看
题意:有n个木板,给出每个木板的左右端点坐标高度,还有每个木板的能量值,一个人初始能力100,从最高的木板开始,每下落到一个木板,得到这个木板的能量值,然后通过这个木板的左右移动到下一个木板,问落到横坐标为0的时候,最大能量值是多少。
题解:因为每个木板的左右端点可以确定下一个木板,明显可以用dp来从最高到最低的得出最大值,可是这里木板有100000个,可以借助线段树来维护每个木板通过左右端点到的下一个木板的编号,这样dp[next] = max(dp[next],dp[cur]+val[next])。
题解:因为每个木板的左右端点可以确定下一个木板,明显可以用dp来从最高到最低的得出最大值,可是这里木板有100000个,可以借助线段树来维护每个木板通过左右端点到的下一个木板的编号,这样dp[next] = max(dp[next],dp[cur]+val[next])。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; struct Plank { int h, lx, rx, val; bool operator < (const Plank& a) const { return h < a.h; } }pla ; int n, idx[N << 2], flag[N << 2], tl , tr , f ; void pushdown(int k) { if (flag[k] != -1) { flag[k * 2] = flag[k * 2 + 1] = flag[k]; idx[k * 2] = idx[k * 2 + 1] = idx[k]; flag[k] = -1; } } void modify(int k, int left, int right, int l, int r, int v) { if (l <= left && right <= r) { idx[k] = v; flag[k] = 1; return; } pushdown(k); int mid = (left + right) / 2; if (r <= mid) modify(k * 2, left, mid, l, r, v); else if (l > mid) modify(k * 2 + 1, mid + 1, right, l, r, v); else { modify(k * 2, left, mid, l, mid, v); modify(k * 2 + 1, mid + 1, right, mid + 1, r, v); } } int query(int k, int left, int right, int pos) { if (left == right) return idx[k]; pushdown(k); int mid = (left + right) / 2; if (pos <= mid) return query(k * 2, left, mid, pos); return query(k * 2 + 1, mid + 1, right, pos); } int main() { while (scanf("%d", &n) == 1) { memset(idx, -1, sizeof(idx)); memset(flag, -1, sizeof(flag)); memset(f, 0, sizeof(f)); pla[0].h = 0, pla[0].lx = 1, pla[0].rx = N - 5, pla[0].val = 0; for (int i = 1; i <= n; i++) scanf("%d%d%d%d", &pla[i].h, &pla[i].lx, &pla[i].rx, &pla[i].val); sort(pla, pla + 1 + n); for (int i = 0; i <= n; i++) { tl[i] = query(1, 1, N - 5, pla[i].lx); tr[i] = query(1, 1, N - 5, pla[i].rx); modify(1, 1, N - 5, pla[i].lx, pla[i].rx, i); } f = 100 + pla .val; for (int i = n; i >= 0; i--) { f[tl[i]] = max(f[tl[i]], f[i] + pla[tl[i]].val); f[tr[i]] = max(f[tr[i]], f[i] + pla[tr[i]].val); } if (f[0] > 0) printf("%d\n", f[0]); else printf("-1\n"); } return 0; }
相关文章推荐
- 简历上的公关战
- IOS中Json解析的四种方法
- 常用js代码
- Magento 默认排序为最新产品在前 How to sort Magento products by date added as default
- axture实训2
- java实现 分类汇总
- 2015.09.10 hihoCoder(C++)
- Leetcode #279 Perfect Squares
- VC6.0 和VS2008 加载IPHlpApi.LIB及IPHlpApi.H 失败 方法
- Leetcode Reverse Linked List
- 1094. The Largest Generation (25)
- P2P之UDP穿透NAT的原理与实现
- 移动客户端开发的一点小小的思考
- atlas tutorial
- 剑指Offer面试题:27.最小的k个数
- MySQL for mac如何调出命令行客户端MySQL Command Line Client
- CentOS6.5下kafka+ZooKeeper下载与安装详细教程-多机版本2-附录
- 基于jqery插件 实现粘贴板
- CentOS6.5下kafka+ZooKeeper下载与安装详细教程-多机版本2
- 蓝懿iOS培训日志8 控件学习2