963 AlvinZH打怪刷经验

思路

这不是一道普通的01背包题。大家仔细观察数据的范围,可以发现如果按常理来的话,背包容量特别大,你也会TLE。

方法一:考虑01背包的一个常数优化----作用甚微。考虑到V很大时,由于只需要dp[V]的值,倒推前一个物品,只要知道dp[V-Wn]即可。以此类推,对以第j个背包,其实只需要知道到dp[V-sum{w[j..n]}]即可。这是DP无后效性的理解。

什么是01背包常数优化?

这种方法可以卡着时间点过这题,具体参考参考代码一。

方法二:动态规划需要变通!!!发现价值之和的最大值只有10^5,逆向思维,容量与价值概念互换,用最大价值来求最小容量;即,把价值之和看作是背包容量,转化为求最大价值对应的最小容量进行背包。

效率很高,不是上一种方法能比的,毕竟差了好几个数量级。具体参考参考代码二。

参考代码一

  1. //
  2. // Created by AlvinZH on 2017/11/16.
  3. // Copyright (c) AlvinZH. All rights reserved.
  4. //
  5. #include <cstdio>
  6. #include <iostream>
  7. #include <cstring>
  8. #define INF 0x3f3f3f3f
  9. using namespace std;
  10. int n, m, sum;
  11. int Weight[102];//体积
  12. int Value[102];//价值
  13. int dp[100005];
  14. int main()
  15. {
  16. while(~scanf("%d %d", &n, &m))
  17. {
  18. int wSum = 0, vSum = 0;
  19. memset(dp, INF, sizeof(dp));
  20. for (int i = 0; i < n; ++i) {
  21. scanf("%d %d", &Weight[i], &Value[i]);
  22. wSum += Weight[i];
  23. vSum += Value[i];
  24. }
  25. dp[vSum] = wSum;
  26. for (int i = 0; i < n; ++i) {
  27. for (int j = Value[i]; j <= vSum; ++j) {
  28. if(dp[j] - Weight[i] >= 0)
  29. dp[j - Value[i]] = min(dp[j-Value[i]], dp[j]-Weight[i]);
  30. }
  31. }
  32. for (int i = vSum; i >= 0; --i) {
  33. if(dp[i] <= m) {
  34. printf("%d\n", i);
  35. break;
  36. }
  37. }
  38. }
  39. }

参考代码二

  1. //
  2. // Created by AlvinZH on 2017/11/16.
  3. // Copyright (c) AlvinZH. All rights reserved.
  4. //
  5. #include <cstdio>
  6. #include <iostream>
  7. #include <cstring>
  8. #define INF 0x3f3f3f3f
  9. using namespace std;
  10. int n, m, sum;
  11. int Weight[102];//体积
  12. int Value[102];//价值
  13. int dp[100005];
  14. int main()
  15. {
  16. while(~scanf("%d %d", &n, &m))
  17. {
  18. int wSum = 0, vSum = 0;
  19. memset(dp, INF, sizeof(dp));
  20. for (int i = 0; i < n; ++i) {
  21. scanf("%d %d", &Weight[i], &Value[i]);
  22. wSum += Weight[i];
  23. vSum += Value[i];
  24. }
  25. dp[0] = 0;
  26. dp[vSum] = wSum;
  27. for (int i = 0; i < n; ++i) {
  28. for (int j = vSum; j >= Value[i]; --j) {
  29. if(dp[j] > dp[j-Value[i]] + Weight[i])
  30. dp[j] = dp[j-Value[i]] + Weight[i];
  31. }
  32. }
  33. for (int i = vSum; i >= 0; --i) {
  34. if(dp[i] <= m) {
  35. printf("%d\n", i);
  36. break;
  37. }
  38. }
  39. }
  40. }

963 AlvinZH打怪刷经验(背包DP大作战R)的更多相关文章

  1. AlvinZH掉坑系列讲解(背包DP大作战H~M)

    本文由AlvinZH所写,欢迎学习引用,如有错误或更优化方法,欢迎讨论,联系方式QQ:1329284394. 前言 动态规划(Dynamic Programming),是一个神奇的东西.DP只能意会, ...

  2. 976 AlvinZH想回家(背包DP大作战T)

    976 AlvinZH想回家 思路 如果在第i小时有一些飞机延误,那么一架飞机的c值越大,这一小时产生的损失也越大.而使这一小时产生的损失尽可能的小并不会导致接下来时间产生的损失增大.因此应当每一小时 ...

  3. 977 AlvinZH过生日(背包DP大作战S)

    977 AlvinZH过生日 思路 难题.逆推DP. 要明确dp的状态只与是否有选择权有关,而与选择权在谁手里无关.因为不论选择权在谁手里,那个人都会尽可能的获得最大的蛋糕重量. dp[i]表示分配到 ...

  4. 991 AlvinZH的奇幻猜想----整数乘积plus(背包DP大作战P)

    914 AlvinZH的奇幻猜想----整数乘积puls 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移 ...

  5. 906 AlvinZH的奇幻猜想----整数乘积(背包DP大作战O)

    906 AlvinZH的奇幻猜想----整数乘积 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移方程为: ...

  6. 851 AlvinZH的鬼畜密码(背包DP大作战N)

    851 AlvinZH的鬼畜密码 思路 难题.动态规划. 先判断字符串是否合理(可翻译),然后分段处理,每一小段用动态规划求出解法数. dp[i]:字符串str[0~i]的解法数.通过判断str[i] ...

  7. DP大作战—组合背包

    题目描述 组合背包:有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包). DD大牛的伪代码 for i = 1 to N if 第i件物品属 ...

  8. DP大作战——多重背包

    题目描述 在之前的上机中,零崎已经出过了01背包和完全背包,也介绍了使用-1初始化容量限定背包必须装满这种小技巧,接下来的背包问题相对有些难度,可以说是01背包和完全背包的进阶问题. 多重背包:物品可 ...

  9. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

随机推荐

  1. 更改IDEA高亮字体背景颜色

    IDEA工具中依次进入file -> settings -> editor -> colors Scheme -> general,在右侧窗口中将result.i  都改成自己 ...

  2. Solidity智能合约调用智能合约

    来源:https://medium.com/@blockchain101/calling-the-function-of-another-contract-in-solidity-f9edfa921f ...

  3. 1、SSH框架整合

    1.建立项目 2.导入SSHjar包 http://pan.baidu.com/s/1hsELr04 3.引入web.xml文件 <?xml version="1.0" en ...

  4. mysql 字符串操作

    -- 字符串的长度 SELECT LENGTH('abc'),LENGTH('我的家'); SELECT CHAR_LENGTH('abc'),CHAR_LENGTH('我的家'); -- 合并字符串 ...

  5. 我是如何在SQLServer中处理每天四亿三千万记录的(转)

    出处:http://www.cnblogs.com/marvin/p/HowCanIHandleBigDataBySQLServer.html 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章 ...

  6. Open Type vs Open resource

    Open Type 可查询所有java 类型,包括.java .class Open Resource 只能打开 .java 等 ,不能打开 .class 相同点 都可以使用 ? * 通配符

  7. [Lua快速了解一下]Lua的model

    我们可以直接使用require(“model_name”)来载入别的lua文件,文件的后缀是.lua.载入的时候就直接执行那个文件了.比如: 我们有一个hello.lua的文件: print(&quo ...

  8. 学习python2

    字符串遍历 列表遍历 元组遍历 字典遍历 <1> 遍历字典的key(键) <2> 遍历字典的value(值) <3> 遍历字典的项(元素) <4> 遍历 ...

  9. Sed的使用方法简介

    =============Sed================== Sed:是一款流编辑工具,用来对文本进行过滤与替换工作,特别是当你想对几十个配置文件进行统一修改时,你会体会到它的魅力:Sed通过 ...

  10. win7 64位备份时, 无法启动服务,0x80070422

    问题:当win7 64位系统在备份的时候,无法启动备份服务,错误代码:0x80070422 解决方法:计算机->管理->服务 找到 Block Level Backup Engine Se ...