【OpenJudge 2.6-1775】讲一讲背包问题(一)【背包DP】

1775:采药

描述

辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入

输入的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出

输出只包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

样例输入

70 3
71 100
69 1
1 2

样例输出

  3

我从学DP 到现在已经过去两个月了,现在唯一就是知道DP是动态规划,剩下就咸鱼了。所以我决定复习DP,写写DP的题。

来说一说今天的主题:背包问题。背包问题最开始是这样的:现在你有一个容量有限制的背包,还有许多有体积和价值的物品,物品的体积和价值各不相同。而背包问题问的就是在限定的体积下,你最多能装多大价值的物品。

基本上裸的背包题都是这个套路,当然价值可以变成时间什么的,像“采药”这道题,背包就是有限的时间,而价值就是采一种药的时间(多写写背包问题就能明显发现一道题是不是背包)。

好了,开始上课。

首先,给出背包问题的模板
#include <bits/stdc++.h>
using namespace std;

const int maxn = 102, maxT = 1005;
int f[maxn][maxT];  //i个物品选择一些物品, 总体积为j
int main()
{

    int T, n; cin >> T >> n;

    for (int i = 1; i <= n; ++i)
    {
        int V, C; cin >> V >> C;

        for (int j = 0; j <= T; ++j)
            f[i][j] = f[i - 1][j]; //不选这个物品

        for (int j = 0; j + V <= T; ++j) //选这个物品
            if ((f[i][j + V]) < (f[i - 1][j] + C))
                (f[i][j + V]) = (f[i - 1][j] + C);
    }
    cout << f[n][T] << endl;
}
能看懂的就可以跳过下面的部分然后去A题了,没看懂的不要着急,我会慢慢讲。

先解释一下各变量和数组都是干什么的。f[i][j]表示背包容量为j时选了i件物品的最大价值,T,n分别表示背包容量,物品件数,V C就是每件物品的体积和价值。每输入一组数据,就将状态更新一次,代码的注释也写得很清楚,我们的策略是默认先不选择这个物品,所以f[i][j] = f[i - 1][j]是将当前状态记为和之前一样的状态,就相当于没有选择这个物品;而在更新的时候我们判断只要装入它不超容量,并且价值比原价值大的话,就装入它。

P.S.这是一道极其典型的背包问题,是最基础的背包问题,因为状态只有“0”和“1”(不装和装)两种,所以被称作“01背包”。
时间: 2024-11-06 20:59:43

【OpenJudge 2.6-1775】讲一讲背包问题(一)【背包DP】的相关文章

有依赖的背包问题(背包九讲)

问题: 这种背包问题的物品间存在某种"依赖"的关系.也就是说,i依赖于j,表示若选物品i,则必须选物品j.为了简化起见,我们先设没有某个物品既依赖于别的物品,又被别的物品所依赖:另外,没有某件物品同时依赖多件物品. 算法: 这个问题由NOIP2006金明的预算方案一题扩展而来.遵从该题的提法,将不依赖于别的物品的物品称为"主件",依赖于某主件的物品称为"附件".由这个问题的简化条件可知所有的物品由若干主件和依赖于每个主件的一个附件集合组成.按照背

二维费用背包问题(背包九讲)

------------------------------------------ 前言: 对于一些背包问题,重点还是在于如何找出"背包容量"和"各种代价",以及价值,如此问题便迎刃而解了.下午 打篮球居然下冰雹了,悲催了.... ------------------------------------------ 问题: 二维费用的背包问题是指:对于每件物品,具有两种不同的费用:选择这件物品必须同时付出这两种代价:对于每种代价都有 一个可付出的最大值(背包容量)

分组的背包问题(背包九讲)

在使用Ubuntu作为开发环境时经常需要在全局安装一些依赖框架等,这个时候就常常需要用到root权限,但是在Ubuntu下第一次使用su命令时会提示认证失败:查找资料后发现Ubuntu下root权限默认是锁定的,可能是处于安全考虑,但是作为开发人员肯定是需要root权限的. 在命令行中可以输入下面命令设置root密码,这样就能随时使用root权限了: [email protected]:~$ su 密码: su:认证失败 [email protected]:~$ sudo passwd [sud

混合三种背包问题(背包九讲)

问题: 如果将P01.P02.P03混合起来.也就是说,有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包).应该怎么求解呢? 01背包与完全背包的混合: 考虑到在P01和P02中给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类物品可以取无限次,那么只需在对每个物品应用转移方程时,根据物品的类别选用顺序或逆序的循环即可,复杂度是O(VN).伪代码如下: for i=1..N if 第i件物品属于01背包 for v

讲一讲什么叫阻塞非阻塞同步异步

1.讲一讲什么叫阻塞非阻塞同步异步全是用来形容方法的,形容一个方法返回值状态的. 2.io读取,网络读取,jdbc读取,这些流的操作都是bio的,都是阻塞的. 3.所以沃恩一般在处理io操作时,都采用多线程来提高bio的效率. 4.io操作,就是本地文件,网络,数据嘛嘛.所以在这三种读取数据时,都要采用多线程提高效率. 5.多线程处理阻塞方法时,只不过是避免了主线程的阻塞,但是让子线程,也就是处理每个http request的线程去发生阻塞了. 6.传统的古老的开发方式: 单线程执行阻塞方法->

经典面试题|讲一讲JVM的组成

JVM(Java 虚拟机)算是面试必问的问题的了,而但凡问 JVM 一定会问的第一个问题就是:讲一讲 JVM 的组成?那本文就注重讲一下 JVM 的组成. 首先来说 JVM 的组成分为,整体组成部分和运行时数据区组成部分,一般开发者关注的和面试官问的都是后者,但本文会详细讲解以上两个组成部分. 一.JVM 整体组成 JVM 整体组成可分为以下四个部分: 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) 本地库接口

背包问题-01背包

*/--> 背包问题-01背包 Table of Contents 1 问题描述 2 问题思路 2.1 问题定义 2.2 实例演讲 3 问题思考 3.1 优化-定义问题 3.1.1 索引的改变 3.1.2 顺序的改变 3.2 优化-复杂度 3.3 初始值的思考 4 问题延伸 4.1 01背包问题的其他解法 4.2 01背包问题的实际引用 5 参考阅读 1 问题描述 背包问题主要分为三种:01背包 完全背包 多重背包. 01背包就是本文要讨论的问题. 有N件物品和一个容量为W的背包,每种物品 均只

第二讲 完全背包问题(对背包九讲的学习)

学习自:背包九讲 题目 有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路: 完全背包和01背包的区别是一个物品可以被拿无限次,我们之前01背包是拿或者不拿的max,比较,然后我们处理完全背包的时候每个物品拿多少次就好了 每个物品最优拿法=max(不拿,拿一个,拿两个,...,拿n个),抛出个问题,n难道是无限吗?显然不是,大前提是背包总空间或者说处理到第i个物

让菜鸡讲一讲费用流(EK)

让我再讲一个故事吧. 又有一些小精灵要准备从银月城(S)迁徙到Nibel山(T). 这两个地方之间的道路构成了一个网络. 每个道路都有它自己的容量,这决定了每天有多少小精灵可以同时从这儿通过. 和上一篇不同的是,由于上次迁徙的规模很大, 吸引了其它一些种族的注意, 这次每条道路都会有一些人/兽人/哥布林/...向精灵们征收过路费, 现在精灵们想知道,在花费最小的情况下,它们迁徙的速度最大是多少只每天. 费用流=最小费用最大流 在要求流最大的情况下要求费用最小,好像原来的isap已经派不上用场了呢