一、问题描述

物品无限的背包问题:有n种物品,每种均有无穷多个。第 i 种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为 C 的背包中,求使得背包内物品总体积不超过C的前提下重量的最大值。1≤n≤100, 1≤Vi≤C≤10000, 1≤Wi≤1000000.

二、解题思路

我们可以先求体积恰好为 i 时的最大重量(设为d[i]),然后取d[i]中的最大值(i ≤ C)。与之前硬币问题,“面值恰好为S”就类似了。只不过加了新属性——重量,相当于把原来的无权图改成带权图,即把“+1”变成“+W[j]”。这样,问题就变成了求以C为起点、终点任意的,边权之和最大的路径。

三、代码实现

1、记忆化搜索

之前纠结这种方法的时间复杂度,先给结果:O(maxn * maxc)。因为计算dp(s)时,如果dp[i]中i是从0-->C,

则dp[i] = max(dp[i],dp[i - V[j]] + W[j]),dp[i - V[j]]已经计算出来且保存,相当于得到dp[i]没有花费时间。如果dp[i]中i是从C-->0,

每次计算的都被保存且只计算一次,有几次小的递归,也相当于没有花费时间。

 #include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std; const int INF = 0x3f3f3f3f;
const int maxn = + ;
const int maxc = + ;
int n,V[maxn],W[maxn],C;
int d[maxc]; //d[i]表示总体积恰好为i时的最大重量 int dp(int s)
{
int& ans = d[s];
if (ans != -) return ans;
ans = - INF;
for (int i = ; i < n; i++)
{
if (s >= V[i]) ans = max(ans, dp(s - V[i]) + W[i]);
}
return ans;
}
void slove()
{
memset(d, -, sizeof(d));
d[] = ;
int res = -;
for (int i = 0; i <= C; i++)
res = max(res, dp(i));
printf("%d\n", res);
} int main()
{
while (scanf("%d",&n) == && n)
{
scanf("%d", &C);
for (int i = ; i < n; i++)
scanf("%d%d", &V[i], &W[i]); slove();
}
return ;
}

2、递推式

这种写法时间复杂度十分显然,与记忆化搜索相同,都是O(maxn * maxc)。但必须注意循环的顺序,比如容量只能从0-->C,而不能反过来,前一种写法则没有循环的顺序要求。

 void slove()
{
fill(d, d + n, -INF);
d[] = ;
int res = -;
for (int i = ; i <= C; i++) //容量的循环顺序只能是从小到大
{
for (int j = ; j < n; j++)
{
if(i >= V[j]) d[i] = max(d[i], d[i - V[j]] + W[j]);
}
res = max(res, d[i]);
}
printf("%d\n", res);
}

3、两者比较

在得到状态转移方程之后,还需要思考如何编写程序。尽管在很多情况下,记忆化搜索程序更直观、易懂,但在0-1背包中递推法更理想。因为已知状态转移方程后,递推法的难点是循环顺序,而有了“阶段”定义后,循环顺序变得十分显然。

由DAG到背包问题——记忆化搜索和递推两种解法的更多相关文章

  1. UVA_437_The_Tower_of_the_Babylon_(DAG上动态规划/记忆化搜索)

    描述 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  2. ACM/ICPC 之 简单DP-记忆化搜索与递推(POJ1088-滑雪)

    递推型DP 将每个滑雪点都看作起点,从最低点开始逐个由四周递推出到达此点的最长路径的长度,由该点记下. 理论上,也可以将每一点都看作终点,由最高点开始计数,有兴趣可以试试. //经典DP-由高向低海拔 ...

  3. 专题1:记忆化搜索/DAG问题/基础动态规划

      A OpenJ_Bailian 1088 滑雪     B OpenJ_Bailian 1579 Function Run Fun     C HDU 1078 FatMouse and Chee ...

  4. LightOJ1417 Forwarding Emails(强连通分量+缩点+记忆化搜索)

    题目大概是,每个人收到信息后会把信息发给他认识的一个人如此下去,问一开始要把信息发送给谁这样看到信息的人数最多. 首先找出图中的SCC并记录每个SCC里面的点数,如果传到一个SCC,那么里面的人都可以 ...

  5. bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果【tarjan+记忆化搜索】

    对这个奇形怪状的图tarjan,然后重新连边把图变成DAG,然后记忆化搜索即可 #include<iostream> #include<cstdio> using namesp ...

  6. 动态规划——I 记忆化搜索

    Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  7. 【bzoj1415】[Noi2005]聪聪和可可 期望记忆化搜索

    题目描述 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...

  8. POJ_1088_(dp)(记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 95792   Accepted: 36322 Description ...

  9. NYOJ16|嵌套矩形|DP|DAG模型|记忆化搜索

    矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a& ...

随机推荐

  1. SqlServer2012——Select,分组,排序、插入

    1.select 简单语句 --select语句 * --select子句 * AS result --select子句,可以将结果保存在result中 ~~~~~~~~~~~~~~~~~~~~~~~ ...

  2. [WIP]express 入门

    创建: 2019/04/10  install  创建并移动进新文件夹 mkdir sample_app cd sample_app  创建package.json并导入express npm ini ...

  3. lightoj 1078【同余定理】

    题意: 给你一个n和一个数 digit ,问你最少需要多少个 digit 使得整除于n; 思路: 同余定理(a+b)%n=(a%n+b%n)%n; (m%n+m%n*10+m%n*100+m%n*10 ...

  4. 强大的在线web编辑器UEditor

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码. UEditor在线演示地址:http://u ...

  5. DataGridView DataSource 如何实现排序

    将数据绑定在下面的类中就可以实现排序 public class SortableBindingList<T> : BindingList<T> { private ArrayL ...

  6. [Xcode 实际操作]九、实用进阶-(32)项目的打包上传和提交审核以及下架处理

    目录:[Swift]Xcode实际操作 本文将演示如何将一个应用程序进行打包上传,并提交审核以及下架处理. 点击项目[DemoApp]->[Build Settings]编译设置->[Pr ...

  7. vue2.0.js基础开发使用心得(结合实际项目对数据的增删改查)

    1.首先申明,没有使用vue 的组件,以及脚手架等,都是一些基础语法的使用. ------------------------------------------------------------- ...

  8. Windows服务使用Windsor容器

    该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇. Windsor是ABP框架自带的IOC容器. 关于什么是IOC,你可以Bing或者Go ...

  9. Lock1

    分布式锁1 Java常用技术方案 前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际 ...

  10. MQ简介1

    站在巨人的肩膀上 关于消息队列的使用 一.消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息 ...