题目描述:

对于给出的n个物品,每个物品有一个价格p[i],你有m元钱,求最多能买的物品个数,以及有多少种不同的方案

题目分析:

类似01背包的题目,一般的01背包问题我们遇到的是求n个物品,有m的容量,每个有w[i]的花费,求出容量范围内的价值的最大值,动态转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + value[i]),dp[i][j]存放前i种物品,容量为j时价值的最大值,优化空间之后是dp[j] = max(dp[j], dp[j-w[i]] + value[i]),而用此题去类比01背包的题目的语境,此时把每次纪念品的价格都当做是1,我们需要求的是给定的容量m的最大价值的搭配方法

原来就只需要求最大价值是多少,相当于多了一个维度存放搭配的数目,每一个i对应着一个二维数组,当更新当前第i个二维数组时,是根据第i-1个二维数组里的值更新的,所以此时需要用到三维数组存放,优化空间后可以用二维数组,且第2,3层循环都需要从大到小,避免干扰

套用01背包对动态转移方程进行推导:优化之前,dp[i][j][k]表示前i件物品,当有j元钱(不超过j元钱),可以购买k个物品的种数,dp[i][j][k] = dp[i-1][j][k] + dp[i-1][j-p[i]][k-1],(前i个物品的有j元,买k个物品的种数为前i-1个物品j元买k个(第i个不买)或者i-1个物品j-p[i]元买k-1件物品的种数(第i个买)),优化空间后为dp[j][k] = dp[j][k] + dp[j-p[i]][k-1]

需要注意的是初始化dp[i][0]都为1,意思是i元钱买0种物品的选择方案有1种就是不买

代码:

 #include<iostream>
#include<string.h>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std; int p[];
int dp[][]; int main(){
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) scanf("%d", &p[i]);
sort(p+, p+n+);
int sum = ;
int ma = ;
for(int i = ; i <= n; i++){
if(sum + p[i] <= m){
sum += p[i];
ma = i;
}
}
memset(dp, , sizeof(dp));
for(int i = ; i <= m; i++) dp[i][] = ;
for(int i = ; i <= n; i++){
for(int j = m; j >= p[i]; j--){
for(int k = ma; k >= ; k--){
dp[j][k] += dp[j-p[i]][k-];
}
}
}
if(ma != ){
printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n", dp[m][ma], ma);
}else{
printf("Sorry, you can't buy anything.\n");
}
}
return ;
}

hdu2126 类01背包(三维数组的二维空间优化)的更多相关文章

  1. POJ3211--分类01背包

    Washing Clothes Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 9700 Accepted: 3110 Desc ...

  2. 51 Nod 1007 正整数分组【类01背包】

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组, ...

  3. UVA - 12563 Jin Ge Jin Qu hao(劲歌金曲)(0-1背包+滚动数组)

    题意:在KTV唱歌剩下的t秒时间内,决定选最爱的n首歌中的一部分歌,在时间结束之前唱一首时长678秒的<劲歌金曲>,使得唱的总曲目尽量多(包括<劲歌金曲>),在此前提下尽量晚的 ...

  4. FOJProblem 2214 Knapsack problem(01背包+变性思维)

    http://acm.fzu.edu.cn/problem.php?pid=2214 Accept: 4    Submit: 6Time Limit: 3000 mSec    Memory Lim ...

  5. hpu 1267 Cafeteria (01背包)

    1267: Cafeteria [DP] 时间限制: 1 Sec 内存限制: 128 MB提交: 76 解决: 31 统计 题目描述 Nanae把饥肠辘辘的josnch带去一家自助餐厅,面对面前眼花缭 ...

  6. HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】

     Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the n ...

  7. 算法笔记(c++)--关于01背包的滚动数组

    算法笔记(c++)--关于01背包的滚动数组 关于01背包问题:基本方法我这篇写过了. https://www.cnblogs.com/DJC-BLOG/p/9416799.html 但是这里数组是N ...

  8. HDU 5234 Happy birthday --- 三维01背包

    HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置 ...

  9. C++类实现三维数组算法

    在学习北京大学教授的<程序设计实习 / Practice on Programming>中,遇到了一个习题,花了很长时间研究,现在分享出来: 课题地址:https://class.cour ...

随机推荐

  1. 第02组 Beta冲刺(4/4)

    队名:十一个憨批 组长博客 作业博客 组长黄智 过去两天完成的任务:了解整个游戏的流程 GitHub签入记录 接下来的计划:继续完成游戏 还剩下哪些任务:完成游戏 燃尽图 遇到的困难:没有美术比较好的 ...

  2. [LeetCode] 269. Alien Dictionary 另类字典

    There is a new alien language which uses the latin alphabet. However, the order among letters are un ...

  3. 【07月16日】A股滚动市净率PB历史新低排名

    2010年01月01日 到 2019年07月16日 之间,滚动市净率历史新低排名. 上市三年以上的公司,2019年07月16日市净率在30以下的公司. 来源:A股滚动市净率(PB)历史新低排名. 1 ...

  4. SQLserver 存储过程游标使用

    ALTER PROCEDURE [dbo].[p_DeleteStretchData] ) , ) AS BEGIN ) ) declare @stretch_cursor cursor -- 声明游 ...

  5. oracle数据库表约束、视图、索引—该记录为本人以前微博的文章

    一.Oracle 数据库常用操作续关于创建表时创建约束1.创建表的时候增加约束----约束是定义表中的数据应该遵循的规则或者满足的条件----约束是建立在列上的,让某一列或者某几列数据之间有约束--- ...

  6. 将Prometheus alerts保存到elasticsearch

    Prometheus产生的告警通常会发送到alertmanager,当使用alertmanager时,其告警信息仅存在于alertmanager的内存中,无法持久化.故实现了小工具,用于将Promet ...

  7. for循环居然还可以这样写

    公司代码有点坑,查找问题,发现for循环的写法不是固定条件在中间,写反了也是可以运行的.比如:下面一个简单的for循环 int m=0; for(int i=0;i>3;i++){ m=m+i; ...

  8. j2ee的容器:web容器和ejb容器的概念

    在J2EE中,容器充当的是中间件的角色. 两种主要容器的概念 Web容器 给处于其中的应用程序组件(JSP.Servlet)提供一个环境,使得JSP,Servlet能直接和容器中的环境变量.接口交互而 ...

  9. Linux系统安装snmp服务

    Linux安装snmp详解 Snmp一种网络之间的传输协议,通过snmp可以采集很多指标比如cpu.内存及磁盘的信息,现在越来越多的网络设备基本上都支持snmp,本文介绍了snmp的安装过程. 二.安 ...

  10. Git拉取远程分支命令

    如果我们想从Git仓库中拉取一个分支到本地,此处假如远程分支为develop,本地要创建的分支为dev,可以使用以下命令: git init    //初始化本地Git仓库 git remote ad ...