CF28D Don't fear, DravDe is kind 背包
题目传送门:http://codeforces.com/problemset/problem/28/D
题意:给你$N$个物品,每个物品有其价格$P_i$,之前必须要买的物品价格和$L_i$,之后必须要买的物品价格和$R_i$和价值$W_i$。试给出一种物品的选择方案,使得满足所有选择的物品的条件且选择物品的价值和最大(物品的选择顺序必须要与原来的顺序相同)。$N \leq 10^5 , P , L , R \leq 10^5 , W \leq 10^4$
像背包DP,所以就是背包DP(雾
我们能够发现从物品$i$转移到物品$j$的充要条件是:$R_i=R_j+P_j$且$L_i+P_i=L_j$。将二式相加得$P_i+L_i+R_i=P_j+L_j+R_j$,也就是说$P+L+R$相等的物品才能够互相转移。所以我们可以考虑使用$vector$存每个$P+L+R$对应的物品,对于每个组跑一次DP。因为每一个物品的转移只能从$L$到$L+P$,所以转移是$O(1)$的,所以DP总复杂度为$O(n)$。注意DP数组的清空推荐使用还原而不是memset,这样还原的复杂度才是$O(n)$。
获得了最大的价值之后,对对应的那一个组别再跑一遍DP,跑出方案。方案的记录可以通过记录某一个物品选择前最后选择的物品来实现。总复杂度为$O(n)$。
注意每一个组别一定要有始有终(也就是选择的物品必须要有$L=0$与$R=0$的物品,也可以通过这一个来剪一些枝降低常数)
关于输出方案其实可以使用递归,但是因为本机会爆栈所以用循环+vector输出
#include<bits/stdc++.h>
#define MAXN 3000010
#define MAXM 200010
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return a;
}
struct thing{
int w , p , l , r , ind;
}now;
vector < thing > v[MAXN];
vector < int > anss;
, maxDir;
bool haveEnd[MAXN];
void out(int dir){
){
anss.push_back(v[maxDir][dir].ind);
dir = last[dir];
}
; i >= ; i--)
printf("%d " , anss[i]);
}
int main(){
int N = read();
; i <= N ; i++){
now.w = read();
now.p = read();
now.l = read();
now.r = read();
now.ind = i;
){
cnt[now.p + now.l + now.r]++;
v[now.p + now.l + now.r].push_back(now);
)
haveEnd[now.p + now.l + now.r] = ;
}
}
memset(maxPri , -0x3f , sizeof(maxPri));
maxPri[] = ;
; i <= ; i++)
if(cnt[i] && haveEnd[i]){
; j < cnt[i] ; j++)
maxPri[v[i][j].l + v[i][j].p] = max(maxPri[v[i][j].l + v[i][j].p] , maxPri[v[i][j].l] + v[i][j].w);
if(maxN < maxPri[i]){
maxN = maxPri[i];
maxDir = i;
}
; j < cnt[i] ; j++)
maxPri[v[i][j].l + v[i][j].p] = -0x3f3f3f3f;
}
memset(last , - , sizeof(last));
memset(k , - , sizeof(k));
; j < cnt[maxDir] ; j++)
if(maxPri[v[maxDir][j].l + v[maxDir][j].p] < maxPri[v[maxDir][j].l] + v[maxDir][j].w){
maxPri[v[maxDir][j].l + v[maxDir][j].p] = maxPri[v[maxDir][j].l] + v[maxDir][j].w;
last[j] = k[v[maxDir][j].l];
k[v[maxDir][j].l + v[maxDir][j].p] = j;
ans[v[maxDir][j].l + v[maxDir][j].p] = ans[v[maxDir][j].l] + ;
}
printf("%d\n" , ans[maxDir]);
out(k[maxDir]);
;
}
CF28D Don't fear, DravDe is kind 背包的更多相关文章
- CF28D Don't fear, DravDe is kind
传送门 题意:\(n\)个位置,每个位置有价值\(v_i\)和重量\(p_i\),要选出一些位置,如果要选位置\(i\),那么前面选的重量之和要为\(l_i\),后面选的重量之和要为\(r_i\),求 ...
- 【神仙题】【CF28D】 Don't fear, DravDe is kind
传送门 Description 一个有N辆卡车的车队从城市Z驶向城市3,来到了一条叫做"恐惧隧道"的隧道.在卡车司机中,有传言说怪物DravDe在那条隧道里搜寻司机.有些司机害怕先 ...
- CodeForces 28D Don't fear, DravDe is kind dp
主题链接:点击打开链接 为了让球队后,删除是合法的.也就是说,对于每一个车辆, l+r+c 一样,按l+r+c分类. 然后dp一下. #include <cstdio> #include ...
- [Codeforces 28D] Do not fear,DravDe is kind
Brief Intro: 对于四元组(v,c,l,r),求其子序列中v最大的和,并使其满足: 1.Ci+Li+Ri相同 2.L1=0,Rn=0 3.Li=Sigma(C1...Ci-1) Soluti ...
- codeforces 28D(dp)
D. Don't fear, DravDe is kind time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- 【USACO 3.1】Stamps (完全背包)
题意:给你n种价值不同的邮票,最大的不超过10000元,一次最多贴k张,求1到多少都能被表示出来?n≤50,k≤200. 题解:dp[i]表示i元最少可以用几张邮票表示,那么对于价值a的邮票,可以推出 ...
- HDU 3535 AreYouBusy (混合背包)
题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下 ...
- HDU2159 二维完全背包
FATE Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- CF2.D 并查集+背包
D. Arpa's weak amphitheater and Mehrdad's valuable Hoses time limit per test 1 second memory limit p ...
随机推荐
- Javascript异步编程之二回调函数
上一节讲异步原理的时候基本上把回掉函数也捎带讲了一些,这节主要举几个例子来具体化一下.在开始之前,首先要明白一件事,在javascript里函数可以作为参数进行传递,这里涉及到高阶函数的概念,大家可以 ...
- Linux 下的 PostgreSQL 数据库+文件通用自动备份脚本
由于 Odoo(原名 OpenERP)自 8.0 以来会生成 CSS,并把附件存储在文件系统中,因此以前单纯备份数据库的脚本已经不够用了.出于实际部署的考虑,我专门写了个较为通用的 Odoo 备份脚本 ...
- Linux Linux内核参数调优
Linux内核参数调优 by:授客 QQ:1033553122 关于调优的建议: 1.出错时,可以查看操作系统日志,可能会找到一些有用的信息 2.尽量不要“批量”修改内核参数,笔者就曾这么干过,结果“ ...
- (网页)js最新手机号码、电话号码正则表达式
正则表达式(regular expression)是一个描述字符模式的对象.使用JavaScript正则表达式可以进行强大的模式匹配和文本检索与替换功能. 手机号码正则表达式验证. function ...
- Djanggo ORM操作
Django ORM那些相关操作 一般操作 看专业的官网文档:https://docs.djangoproject.com/en/1.11/ref/models/querysets/,做专业的程序员 ...
- [20171227]表的FULL_HASH_VALUE值的计算.txt
[20171227]表的FULL_HASH_VALUE值的计算.txt --//sql_id的计算是使用MD5算法进行哈希,生成一个128位的Hash Value,其中低32位作为HASH VALUE ...
- 出现error: stray ‘\357’ in program的根源
分类: 编程语言/ C#/ 文章 这次又遇到这个这种问题,想找到它的根源.找到一个表格: The characters at a glance Here are all the printable c ...
- MySQL使用索引的场景分析、不能使用索引的场景分析
一.MySQL中能够使用索引的典型场景 1.匹配全值.对索引中的列都有等值匹配的条件.即使是在and中,and前后的列都有索引并进行等值匹配. 2.匹配值的范围查询,对索引的值能够进行范围查找. 3. ...
- python学习-判断是否是私网IP地址
判断是否是私网IP地址 私网IP地址范围如下: 192.168.0.0-192.168.255.255 172.16.0.0-172.31.255.255 10.0.0.0-10.255.255.25 ...
- MATLAB插 值 法
MATLAB插 值 法 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 一.实验目的 二.实验原理 三.实验程序 四.实验内容 五.解答 1. 程序 ...