【题目链接】:http://codeforces.com/problemset/problem/777/E

【题意】



让你摆汉诺塔片;

要求在上面的片的外圈大于在下面的片的内圈,且小于下面的片的外圈;

给你n个片;

每个片有属性->外圈半径,内圈半径,高度;

然后让你选择其中的一些片;

使得它们叠起来高度最高;

【题解】



对于外圈半径相同的。

我们知道它们肯定是能够叠在一起的;

且我们可以把这些外圈相同的泛化成一个片;

这个片的外圈半径和原来的一样,内圈半径是这些外圈半径相同的片的内圈半径中最小的那个->即把内圈半径最小的那个放在最上面;->这样就能够最大限度地让上面的片能够多放一点了,且显然是正确的。

然后这个泛化出来的片的高度就是所有这个外圈半径的片的高度的和;

泛化完毕以后;

我们就得到了n个新的,外圈半径全都不同的片;

接下来我们把这些片按照外圈半径从大到小排序;

然后就能做一个类似最长不下降子序列的DP了

即设f[i]为以第i个片作为最上面那个片的最大高度;

f[i]=max(f[j])+h[i],这里j< i且j的内圈半径< r的外圈半径;

这里我们可以写个线段树来优化;

即在边做DP的时候,边维护内圈半径为r[i]的片的f[i]值;

这里的线段树,线段表示的就是内圈半径;值就是f[i]的值;

所以在查的时候query(1..i的外圈半径-1,1,n,1);

更新的时候同理;

写个离散化就行啦



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 1e5+100; struct abc
{
LL a, b, h;
}; int n,totn;
abc a[N],b[N];
LL c[N], ma[N << 2],f[N],ans; bool cmp1(abc a, abc b)
{
return a.b > b.b;
} void up_data(int pos, LL val, int l, int r, int rt)
{
if (l == r)
{
ma[rt] = max(ma[rt], val);
return;
}
int m = (l + r) >> 1;
if (pos <= m)
up_data(pos, val, lson);
else
up_data(pos, val, rson);
ma[rt] = max(ma[rt << 1], ma[rt << 1 | 1]);
} LL query(int L, int R, int l, int r, int rt)
{
if (L > R) return 0;
if (L <= l && r <= R)
return ma[rt];
int m = (l + r) >> 1;
LL temp1 = 0, temp2 = 0;
if (L <= m)
temp1 = query(L, R, lson);
if (R > m)
temp2 = query(L, R, rson);
return max(temp1, temp2);
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
rei(n);
rep1(i, 1, n)
rel(a[i].a), rel(a[i].b), rel(a[i].h);
sort(a + 1, a + 1 + n, cmp1);
rep1(i, 1, n){
int j = i;
LL mi = a[i].a,height = a[i].h;
while (j + 1 <= n && a[j + 1].b == a[i].b) j++,mi = min(mi,a[j].a),height+=a[j].h;
b[++totn].b = a[i].b, b[totn].a = mi, b[totn].h = height;
c[totn] = mi;
i = j;
}
sort(c + 1, c + 1 + totn);
n = totn;
f[1] = b[1].h;
up_data(lower_bound(c + 1, c + 1 + n, b[1].a) - c,f[1], 1, n, 1);
rep1(i, 2, n)
{
int idx = upper_bound(c + 1, c + 1 + n, b[i].b - 1) - c -1;
LL bef = query(1, upper_bound(c + 1, c + 1 + n, b[i].b - 1) - c-1, 1, n, 1);
f[i] = max(f[i], bef + b[i].h);
idx = lower_bound(c + 1, c + 1 + n, b[i].a) - c;
up_data(lower_bound(c + 1, c + 1 + n, b[i].a) - c, f[i], 1, n, 1);
}
ans = f[1];
rep1(i, 2, n)
ans = max(ans, f[i]);
printf("%lld\n", ans);
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}

最新文章

  1. [No000081]SVN学习笔记1-服务端搭建
  2. win7 64的系统安装。net4.0总是提示安装未成功
  3. js数组操作
  4. Hdu 1507 Uncle Tom&#39;s Inherited Land* 分类: Brush Mode 2014-07-30 09:28 112人阅读 评论(0) 收藏
  5. linux笔记_20150417_ubuntu 常见问题_文件_音乐播放器
  6. java8 十大新特性
  7. createThread和_beginthreadex区别
  8. 要搞刷机!从它的尸体上踏过去!钢板云路由!WPR003N复活!成功启动OPENWRT
  9. Spring Security框架下Restful Token的验证方案
  10. 学习笔记《Java多线程编程实战指南》三
  11. Spring cache 使用说明
  12. Required String parameter &#39;images&#39; is not present
  13. django之admin管理工具
  14. Ajax 学习 第一篇
  15. ASP.NET Core 3.0 实战:构建多版本 API 接口
  16. How to calculate elapsed / execute time in Java
  17. (转)机器学习的数学基础(1)--Dirichlet分布
  18. VS2010/MFC编程入门之十八(对话框:字体对话框)
  19. AtCoder Grand Contest 019 B: Reverse and Compare
  20. laravel验证规则

热门文章

  1. day36 09-Hibernate中的事务:事务处理
  2. python实例 函数
  3. python 正则的使用例子和goupby
  4. Visual studio加载项目时报错 尚未配置为Web项目XXXX指定的本地IIS,需要配置虚拟目录。解决办法。
  5. 详解TCP三握四挥
  6. 【JZOJ4928】【NOIP2017提高组模拟12.18】A
  7. hdu4267 线段树
  8. Directx11教程38 纹理映射(8)
  9. PHPCMS快速建站系列之常用标签
  10. Effective Modern C++:03转向现代C++