题目描述:

对于给出的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. C——letterCounter

    /* 一个统计字母(含大小写)出现次数的C程序 */ #include <stdio.h> int main() { ]; char ch; /* initialization */ ; ...

  2. 洛谷P4593 [TJOI2018]教科书般的亵渎

    小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为\(a_i\)​,且每个怪物血量均不相同,小豆手里有无限张"亵渎".亵渎的效果是对所有的怪造成\(1\)点伤害,如果 ...

  3. git的安装及使用

    介绍 1.Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版 ...

  4. Mac修改hosts方法

    总有各种各样的原因需要修改hosts文件,那么就来简介下怎么修改.terminal中打开hosts: sudo vim /private/etc/hosts 打开文件后I开启插入模式,在最后一行添加你 ...

  5. 实验二 Java基础(数据/表达式、判定/循环语句)

    实验二 (一)实验内容 编写简单的计算器,完成加减乘除模运算. 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出. 编写测试代码,测试验证. ...

  6. 微信企业号SDK

    1. 微信企业号SDK class class_wxqiye { var $corpid = CorpID; var $corpsecret = CorpSecret; var $agentid = ...

  7. maven集成命令-U -B -P -e -X

    maven -U clean compile install -e -X -Dmaven.test.skip=true 在持续集成服务器上使用怎样的 mvn 命令集成项目,这个问题乍一看答案很显然,不 ...

  8. Java并发之原子操作类汇总

    当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...

  9. TINYMCE使用手册

    TINYMCE使用手册 这方面的教程会陆续加进来. tinymce.get('f1').getContent();

  10. 手写bind函数

    实现bind函数 参考MDN提供的Polyfill方案 Function.prototype.myBind = function(context){ //这里对调用者做一个判断,如果不是函数类型,直接 ...