题目传送门: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 背包的更多相关文章

  1. CF28D Don't fear, DravDe is kind

    传送门 题意:\(n\)个位置,每个位置有价值\(v_i\)和重量\(p_i\),要选出一些位置,如果要选位置\(i\),那么前面选的重量之和要为\(l_i\),后面选的重量之和要为\(r_i\),求 ...

  2. 【神仙题】【CF28D】 Don't fear, DravDe is kind

    传送门 Description 一个有N辆卡车的车队从城市Z驶向城市3,来到了一条叫做"恐惧隧道"的隧道.在卡车司机中,有传言说怪物DravDe在那条隧道里搜寻司机.有些司机害怕先 ...

  3. CodeForces 28D Don&#39;t fear, DravDe is kind dp

    主题链接:点击打开链接 为了让球队后,删除是合法的.也就是说,对于每一个车辆, l+r+c 一样,按l+r+c分类. 然后dp一下. #include <cstdio> #include ...

  4. [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 ...

  5. codeforces 28D(dp)

    D. Don't fear, DravDe is kind time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  6. 【USACO 3.1】Stamps (完全背包)

    题意:给你n种价值不同的邮票,最大的不超过10000元,一次最多贴k张,求1到多少都能被表示出来?n≤50,k≤200. 题解:dp[i]表示i元最少可以用几张邮票表示,那么对于价值a的邮票,可以推出 ...

  7. HDU 3535 AreYouBusy (混合背包)

    题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下 ...

  8. HDU2159 二维完全背包

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. CF2.D 并查集+背包

    D. Arpa's weak amphitheater and Mehrdad's valuable Hoses time limit per test 1 second memory limit p ...

随机推荐

  1. 阿里SopHix热修复框架

    2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案.阿里AndFix以及微信Tinker(Bugly sdk也集成Tikner ...

  2. 安卓preview不显示的问题

    Render Problem Failed to load AppCompat ActionBar with unknown error 解决方法:将styles.xml文件中的: <resou ...

  3. 为Hexo Next主题添加分享及打赏功能

    博客地址:往事亦如风的博客 要想先看打赏和分享功能效果,请移步我的博客 打赏功能 因为next主题自带打赏功能,所以我们只需要在next的主题配置文件中找到如下代码,image文件夹是我在blog/s ...

  4. python第五十天--paramiko

    python通过paramiko实现,ssh功能 import paramiko ssh =paramiko.SSHClient()#创建一个SSH连接对象 ssh.set_missing_host_ ...

  5. Node.js中文乱码解决方法

  6. Asp.net webForm设置允许表单提交Html

    1. 在表单需要提交Html的页面头部加入  ValidateRequest="false" <%@ Page Language="C#" AutoEve ...

  7. SQLSERVER 死锁

    select request_session_id spid, OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tra ...

  8. Linux下的进程类别(内核线程、轻量级进程和用户进程)--Linux进程的管理与调度(四)

    本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux ...

  9. 5.2Python函数(二)

    目录 目录 前言 (一)偏函数 ==1.说明== ==2.原代码== ==3.显示效果== (二)高阶函数 ==1.说明== ==2.源代码== ==3.运行效果== (三)返回值函数 ==1.说明= ...

  10. January 10th, 2018 Week 02nd Wednesday

    No need to have a reason to love you. Anything can be a reason not to love you. 喜欢你,不需要什么理由:不喜欢你,什么都 ...