http://codeforces.com/gym/101341/problem/K

题意:给出n个区间,每个区间有一个l, r, w,代表区间左端点右端点和区间的权值,现在可以选取一些区间,要求选择的区间不相交,问最大的权和可以是多少,如果权和相同,则选区间长度最短的。要要求输出区间个数和选了哪些区间。

思路:把区间按照右端点排序后,就可以维护从左往右,到p[i].r这个点的时候,已经选择的最大权和是多少,最小长度是多少,区间个数是多少。

因为可以二分找右端点小于等于当前区间的左端点的某个区间(index),然后就有

dp[i] = max(dp[index] + w[index], dp[i]).

这题的我觉得困难的是打印使用了哪些区间,一开始想的方法超时了。

因为用pre数组记录路径,但是路径只是代表当前的解从哪里更新过来的,而不能记录是由哪一个点推出新的最优解。

一开始我用了一个bool型的vis数组判断是否在第i个点更新的答案,然后每次往前找,这样最坏会达到O(n^2)。

但是这样肯定扫了很多重复的情况,因此还可以用递推来构造vis数组,代表当前这个解最后使用了哪一个区间推出来。pre数组也使用递推的形式。

每次如果更新的了,就vis[i] = i,pre[i] = index,否则就vis[i] = vis[i-1], pre[i] = pre[i-1]。

 #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define N 200010
#define INF 0x3f3f3f3f
struct node {
int l, r, w, id;
bool operator < (const node &rhs) const {
if(r != rhs.r) return r < rhs.r;
return l < rhs.l;
}
} p[N];
LL dp[N], len[N];
int tol[N], pre[N], vis[N];
vector<int> ans;
// vis表示新的DP答案由哪个推出来的
// pre表示当前这个点可以由哪一个点跳过来
// dp[i]表示到第i个右端点的时候最大权和
// len[i]表示到第i个右端点的时候最小长度
// tol[i]表示区间个数 int main() {
int n; scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d%d%d", &p[i].l, &p[i].r, &p[i].w), p[i].id = i;
sort(p + , p + + n);
for(int i = ; i <= n; i++) {
dp[i] = dp[i-], len[i] = len[i-], tol[i] = tol[i-], pre[i] = pre[i-], vis[i] = vis[i-];
node now = (node) { INF, p[i].l, , };
int index = upper_bound(p + , p + n + , now) - p - ;
// while(!vis[index] && index) index--;
if(dp[index] + p[i].w > dp[i]) {
dp[i] = dp[index] + p[i].w;
len[i] = len[index] + p[i].r - p[i].l;
tol[i] = tol[index] + ;
pre[i] = index; vis[i] = i;
} else if(dp[index] + p[i].w == dp[i] && len[index] + p[i].r - p[i].l < len[i]) {
len[i] = len[index] + p[i].r - p[i].l;
tol[i] = tol[index] + ;
pre[i] = index; vis[i] = i;
}
// printf("index : %d %d %d %d %lld\n", p[i].id, p[vis[i]].id, p[index].id, p[pre[i]].id, dp[i]);
}
int ed = n;
while(ed) { ans.push_back(p[vis[ed]].id); ed = pre[ed]; }
sort(ans.begin(), ans.end());
printf("%d %lld %lld\n", tol[n], dp[n], len[n]);
for(int i = ; i < ans.size(); i++) printf("%d%c", ans[i], i + == ans.size() ? '\n' : ' ');
return ;
}

Codeforces Gym101341K:Competitions(DP)的更多相关文章

  1. Codeforces 698A:Vacations(DP)

    题目链接:http://codeforces.com/problemset/problem/698/A 题意 Vasya在n天中,有三件事情可以做,健身.比赛或者休息,但是不能连续两天都是比赛或都是但 ...

  2. POJ 2192 :Zipper(DP)

    http://poj.org/problem?id=2192 Zipper Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1 ...

  3. HDU 5791:Two(DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Problem Description   Alice gets two sequences A ...

  4. codeforces 711C Coloring Trees(DP)

    题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...

  5. codeforces#1154F. Shovels Shop (dp)

    题目链接: http://codeforces.com/contest/1154/problem/F 题意: 有$n$个物品,$m$条优惠 每个优惠的格式是,买$x_i$个物品,最便宜的$y_i$个物 ...

  6. Codeforces 1051 D.Bicolorings(DP)

    Codeforces 1051 D.Bicolorings 题意:一个2×n的方格纸,用黑白给格子涂色,要求分出k个连通块,求方案数. 思路:用0,1表示黑白,则第i列可以涂00,01,10,11,( ...

  7. Codeforces 1207C Gas Pipeline (dp)

    题目链接:http://codeforces.com/problemset/problem/1207/C 题目大意是给一条道路修管道,相隔一个单位的管道有两个柱子支撑,管道柱子高度可以是1可以是2,道 ...

  8. Codeforces 704C - Black Widow(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 感觉这种题被评到 *2900 是因为细节太繁琐了,而不是题目本身的难度,所以我切掉这种题根本不能说明什么-- 首先题目中有一个非 ...

  9. POJ 1260:Pearls(DP)

    http://poj.org/problem?id=1260 Pearls Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8 ...

随机推荐

  1. SAAS是否能实现人在家工作的梦想?

    在过去的十年,在人们的工作环境的巨大变化已经发生,越来越多的人选择在家工作. 高租金的办公室,络,快速宽带的广泛应用.这些因素都使得远程办公成为了人们工作中密不可分的一种方式.使用普通手机和办公操作系 ...

  2. Entity framework 配置文件,实现类,测试类

    配置文件信息App.config: 数据库IP地址为192.168.2.186 ,数据库名为 Eleven-Six , 用户名 123456,密码654321 <?xml version=&qu ...

  3. WPF里的一些Effect特效

    原文:WPF里的一些Effect特效 Blend的特效都在Microsoft.Expression.Media.Effects里,用之前添加一下引用. 可以在前台选中对象后直接点击Effect新建一种 ...

  4. Emgu-WPF学习使用-中值模糊

    原文:Emgu-WPF学习使用-中值模糊 实现效果: 实现途径: 前提:Image File-> System.Drawing.Bitmap->Image<Bgr, byte> ...

  5. MVC 创建强类型视图

    •在ViewModel中创建一个类型 •在Action中为ViewData.Model赋值 •在View中使用"@model类型"设置 14 手动创建强类型视图 •在ViewMod ...

  6. 图像滤镜艺术---球面(Spherize)滤镜

    原文:图像滤镜艺术---球面(Spherize)滤镜 球面(Spherize)滤镜 球面滤镜是通过极坐标变换实现图像的球面特效. 代码如下:         //         ///        ...

  7. win10 uwp 萤火虫效果

    原文:win10 uwp 萤火虫效果 本文在Nukepayload2指导下,使用他的思想用C#写出来. 本文告诉大家,如何使用 win2d 做出萤火虫效果. 安装 win2d 安装win2d的方法请使 ...

  8. WPF TextBlock 文字超长截断并显示省略符号

    <TextBlock x:Name=" FontSize="9pt" Margin="0 2 0 0 " VerticalAlignment=& ...

  9. 一个Demo让你掌握Android所有控件

    原文:一个Demo让你掌握Android所有控件 本文是转载收藏,侵删,出处:"安卓巴士"      下面给出实现各个组件的源代码: 1.下拉框实现--Spinner packag ...

  10. 新玩法,CentOS7中LVM通过扩展逻辑卷扩展swap空间

    在我们日常运维工作中,偶尔也会遇到需要扩展swap空间的操作.扩展swap空间的方法很多,现在让我们一起来探讨一下,在LVM下扩展swap空间的方法. 1.查看一下卷组,是否还有空闲空间能用于扩展sw ...