题意: 输入一个n, m表示物品的数量和最大质量,接下来输入n行,每行输入w, c表示物品的质量和价值,求的是不超过m的质量的最大价值。

题解: 很明显是一个01背包问题,但问题是滚动dp能解决空间复杂度,但是解决不了时间复杂度,O(n*m)显然太大了,

因此我们会思考,创建一个三元集dp[ i ] (它包含val, x1, x2 分别表示质量为i时的最大价值,质量为1的物品个数,质量为2的物品个数 )这个w只有1,2,3三个数字,首先从贪心的思想考虑,我们可以对质量为1,2,3的价值进行降序(用a [ w ] [ i ]表示质量为w的第i大的价值)(从性价比角度考虑质量相等肯定先取价值大的),其后可以先预处理只由质量1和 2组成的dp[m].val的最大值,再用质量3去枚举更优的情况。

转移方程分为两部分:

part1:(预处理质量1,2的dp值)

dp[i] = dp[i - 1];

dp[i].val = max(dp[i -1]. val + a[1] [dp[i - 1].x1 + 1], dp[[i - 2].val + a[2] [dp[i - 2].x2 + 1])

注意:在代码实现过程中要考虑a[1] [dp[i - 1].x1 + 1] 和a[2] [dp[i - 2].x2 + 1]是否存在,如果不存在dp直接继承上一个质量就好,不用进行对应的x1 或 x2 的加一操作。

part2:(质量3取枚举更优解)

dp[m].val = max(dp[m].val , dp[m - i * 3].val + ans[i]) (i * 3 <= m)(ans[i]表示前 i 个大的质量为3的价值和(前缀和))

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;struct node{long long val, x1, x2;
}dp[3 * N];long long a[5][N];
long long num[5];
long long n, m, w, v;int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin >> n >> m;for(int i = 1; i <= n; i++){cin >> w >> v;a[w][++num[w]] = v; //存入质量为w的价值}for(int i = 1; i <= 3; i++){sort(a[i] + 1, a[i] + num[i] + 1, greater<int>()); //等质量的物品降序}dp[0].val = 0, dp[0].x1 = dp[0].x2 = 0;for(int i = 1; i <= m; i++){dp[i] = dp[i - 1];//因为是从前往后遍历质量的所以要先继承前一个质量,避免出现w 为1 和 2 的用完以后,后面的dp[].val的值为0;if(i < 2){if(a[1][dp[i - 1].x1 + 1] != 0){ //质量为1的还没有用完才运行这一步否则x1会多加,防止出现不存在质量为1的物品dp[i].val = dp[i - 1].val + a[1][dp[i - 1].x1 + 1];dp[i].x1  = dp[i - 1].x1 + 1;dp[i].x2  = dp[i - 1].x2;}}else{if(dp[i - 1].val + a[1][dp[i - 1].x1 + 1] < dp[i - 2].val + a[2][dp[i - 2].x2 + 1] && a[2][dp[i - 2].x2 + 1] != 0){dp[i].val = dp[i - 2].val + a[2][dp[i - 2].x2 + 1];dp[i].x2  = dp[i - 2].x2 + 1;dp[i].x1  = dp[i - 2].x1; }else{if(a[1][dp[i - 1].x1 + 1] != 0){dp[i].val = dp[i - 1].val + a[1][dp[i - 1].x1 + 1];dp[i].x1  = dp[i - 1].x1 + 1;dp[i].x2  = dp[i - 1].x2;}}}}long long ans[N] = {0};for(int i = 1; i <= num[3]; i++){ans[i] = ans[i - 1] + a[3][i]; //求前缀和} for(int i = 1; i <= num[3]; i++){if(i <= m / 3){dp[m].val = max(dp[m].val ,dp[m - i * 3].val + ans[i]);//必须要遍历完,避免出现ans[i * 3]不起作用,但是ans[(i + 1) * 3]时会比原来的dp[m].val大的情况}else break;}cout << dp[m].val << '\n';
}

E - Selling Souvenirs(动态规划 + 贪心 + 思维(缩小时间复杂度和空间复杂度))相关推荐

  1. codeforces 808 E. Selling Souvenirs (dp+二分+思维)

    题目链接:http://codeforces.com/contest/808/problem/E 题意:最多有100000个物品最大能放下300000的背包,每个物品都有权值和重量,为能够带的最大权值 ...

  2. 贪心/思维题 UVA 11292 The Dragon of Loowater

    题目传送门 1 /* 2 题意:n个头,m个士兵,问能否砍掉n个头 3 贪心/思维题:两个数组升序排序,用最弱的士兵砍掉当前的头 4 */ 5 #include <cstdio> 6 #i ...

  3. 1450F The Struggling Contestant(贪心+思维)

    1450F The Struggling Contestant(贪心+思维) Codeforces Global Round 12 F. The Struggling Contestant 题面:Th ...

  4. cf:B. Patchouli‘s Magical Talisman【数学贪心思维 + 奇偶分析】

    分析 给出一堆数 可以通过相加或除2让它们全部变成奇数 如果全奇数返回0 由于奇数 + 偶数 = 奇数 所以只要有一个奇数就能把偶数和它相加不停的变成奇数 所以只要存在奇数,就可以返回偶数的个数 否则 ...

  5. codeforces Round 21 808E. Selling Souvenirs 【dp好题】

    codeforces Round 21 808E. Selling Souvenirs [dp好题] E. Selling Souvenirs time limit per test 2 second ...

  6. 《C语言程序设计实践》————如何买玫瑰?(贪心思维)

    <C语言程序设计实践>----如何买玫瑰?(贪心思维) 要求:小慧过生日,小明要买玫瑰送她.每枝红玫瑰5元,满5支送1枝,满20枝送5枝.小明一共有n(n>10)元钱,最多能买到多少 ...

  7. 数据结构(02)— 时间复杂度与空间复杂度转换

    1. 时间复杂度转化为空间复杂度 常用的降低时间复杂度的方法有递归.二分法.排序算法.动态规划等,降低空间复杂度的核心思路就是,能用低复杂度的数据结构能解决问题,就千万不要用高复杂度的数据结构. ​ ...

  8. 算法的时间复杂度与空间复杂度介绍

    本文主要介绍算法的时间复杂度和空间复杂度的相关知识. 1 概述 算法(Algorithm)是指用来操作数据.解决程序问题的方法. 对于同一个问题,使用不同的算法,也许最终得到的结果是相同的,但在执行该 ...

  9. 浅淡数据结构时间复杂度和空间复杂度

    文章目录 前言 1.时间复杂度和空间复杂度的相关介绍 1.为什么要引入时间复杂度和空间复杂度的概念 2.什么是时间复杂度和空间复杂度 2.具体示例分析 1.大O法只保留高阶项 2.一般情况关注的是算法 ...

最新文章

  1. PL/SQL Virtual Machine Memory Usage
  2. WebApi_基于Token的身份验证——JWT
  3. ActiveMQ的集群与高可用
  4. 定理在数学中的简写形式_湘教版八年级数学上册知识点总结
  5. SAP License:FICO重要概念(二)-附常用技巧
  6. PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注
  7. 896.Montonic Array - LeetCode
  8. 第四季-专题19-I2C驱动程序设计
  9. Atom : C++如何愉快地与之相处?
  10. 数控机床现场数据采集与边缘计算方案
  11. 手机wap浏览器下载选哪家
  12. 解决hdfs dfs -mkdir input报错`mkdir`:No such file or directory
  13. (MATLAB)绘制三维曲线(plot3/plot)
  14. 起始方位角怎么确定_工程测量中的导线测量,最初的方位角怎么求?
  15. 两个音轨合并_怎样将两个音频合并在一起?超详细教程!
  16. 阿里天池-“Python绘制月饼,云上中秋”:Python元祖冰皮月饼海报制作
  17. ESP32硬件参考详细说明
  18. 在Vue中使用highlight.js
  19. DNP3 模拟器使用教程
  20. 美元汇率Pascal题解

热门文章

  1. 09、查询详细信息和删除记录
  2. 专题:手把手学习硬件基础------3、电感
  3. 2022-2027年中国聚甲醛(POM)市场生产现状与投资前景预测报告
  4. 百趣土壤非靶标代谢组学文献分享,来自Microbiome的灵感
  5. KDE:唯有失去了,才懂得珍惜
  6. 当3万座加油站遇到京东无人科技,3亿车主生活或迎新变化
  7. linux使用命令重命名_如何在Linux上使用重命名命令
  8. android movie 资源释放,Android 资讯类App项目实战 第四章 电影模块
  9. 博通Broadcom SDK源码学习与开发3——Cable Modem Docsis3.0
  10. EOJ 唐纳德与子串 (Easy)