HDU 2126 Buy the souvenirs (01背包,输出方案数)
题意:给出t组数据
每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值
问你所能买到的最大件数,和对应的方案数。
思路:
如果将物品的价格看做容量,将它的件数1看做价值的话,那么用01背包就可以求的花费m钱所能买到的最大件数dp[m]。
但是题目还要求方案数,因此很容易想到再建立一个数组f[j],存储j元钱能买dp[j]个物品的方案数。
在求解01背包的过程中,要分两种情况讨论:
设当前所选的物品为i
1. 若选了物品i后,能买的件数比不选物品i的件数大,即dp[j-val[i]]>dp[j]
那么更新dp[j],同时,f[j]的方案数即为f[j-val[i]]
原因是:假设f[j-val[i]]的方案数为 AB AC 两种,那么在此情况下加个D,为ABD,ACD,仍为两种,所以f[j]=f[j-val[i]]即可
当然,要注意f[j-val[i]]为0的情况,因此当它为0时,f[j]=1,1即为D
2. 若选了物品i后,能买的件数比不选物品i的件数相同,即dp[j-val[i]]==dp[j]
即原先不选第i个物品,所需要的方案数为f[j];而选了物品i的方案数为f[j-val[i]]。
因此,总的方案数即为f[j]+f[j-val[i]]
当然,这里也要注意f[j-val[i]]=0的情况,当它为0时,f[j]+=1,1即为D
一开始,就是这里忘记判断了,导致WA。。。
时间0ms,内存260K,在HDU AC的136个人里面,排名第10,哈哈!
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring> using namespace std;
const int maxn=;
const int maxm=;
int n,m;
int val[maxn]; //存储物品的价格
int dp[maxm]; //dp[j]表示j元钱能买的最大物品件数
int f[maxm]; //f[j]表示j元钱能买dp[j]个物品的方案数
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
val[]=;
for(int i=;i<=n;i++)
scanf("%d",&val[i]);
memset(f,,sizeof(f));
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++){
for(int j=m;j>=val[i];j--){
if(dp[j-val[i]]+>dp[j]){
dp[j]=dp[j-val[i]]+;
if(f[j-val[i]])
f[j]=f[j-val[i]]; //当f[j-val[i]]>0时,直接赋值即可
else
f[j]=; //当f[j-val[i]]=0时,应该算1种,即当前选择的第i件物品
}
else if(dp[j-val[i]]+==dp[j]){
if(f[j-val[i]])
f[j]+=f[j-val[i]]; //当f[j-val[i]]>0时,直接加上即可
else
f[j]+=; //当f[j-val[i]]=0时,应该算1种,即当前选择的第i件物品
}
}
}
if(dp[m]==){
printf("Sorry, you can't buy anything.\n");
}
else{
printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n",f[m],dp[m]);
}
}
return ;
}
HDU 2126 Buy the souvenirs (01背包,输出方案数)的更多相关文章
- hdu 2126 Buy the souvenirs(记录总方案数的01背包)
Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- hdu 2126 Buy the souvenirs 二维01背包方案总数
Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- hdu 2126 Buy the souvenirs 买纪念品(01背包,略变形)
题意: 给出一些纪念品的价格,先算出手上的钱最多能买多少种东西k,然后求手上的钱能买k种东西的方案数.也就是你想要买最多种东西,而最多种又有多少种组合可选择. 思路: 01背包.显然要先算出手上的钱m ...
- Buy the souvenirs---hdu2126(01背包输出方案数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 有n个物品每个物品的价格是v[i],现在有m元钱问最多买多少种物品,并求出有多少种选择方法: 如 ...
- hdu 2126 Buy the souvenirs 【输出方案数】【01背包】(经典)
题目链接:https://vjudge.net/contest/103424#problem/K 转载于:https://blog.csdn.net/acm_davidcn/article/detai ...
- [HDU 2126] Buy the souvenirs (动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解 ...
- HDU 5234 Happy birthday --- 三维01背包
HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置 ...
- UVA 624 CD(01背包+输出方案)
01背包,由于要输出方案,所以还要在dp的同时,保存一下路径. #include <iostream> #include <stdio.h> #include <stri ...
- HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解)
HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解) 题意分析 要先排序,在做01背包,否则不满足无后效性,为什么呢? 等我理解了再补上. 代码总览 #in ...
随机推荐
- C# 将DataTable装换位List<T> 泛型
public List<T> GetList<T>(DataTable dt) where T:new() { List<T> DateLists = new Li ...
- C/C++ 对常见字符串库函数的实现
在c中的string.h头文件中存在很多对字符串进行操作的函数,利用这些函数可以方便的对字符串进行操作.下面将对常见的字符串函数进行解释和实现. strcpy 函数原型:char* _strcpy(c ...
- 【转】IT领域技能图谱
- MIFARE系列6《射频卡与读写器的通讯》
1. 复位应答(Answer to request) 读写器呼叫磁场内的卡片,卡片对呼叫做出应答.对刚进入磁场得到电复位处于休闲状态的卡片,卡请求(REQA,0x26):对于已进行过读写操作并进入休眠 ...
- golang的nil
golang中什么样的类型可以赋值nil? 类型文档中有注定"uninitialized value is nil"的类型都可以赋值nil. golang的基本类型不能赋值nil: ...
- 关于开始学习Leetcode的第一帖
从明天开始,白天在实验室完成工作,晚上来图书馆换个环境去学习算法数据结构等计算机基础性的技能.在LeetCode这个平台上做题. 现在感觉自己在算法和数据机构这方面实在是太薄弱了,需要慢慢的捡起来来, ...
- [转]How do I use software from a PPA
[转]How do I use software from a PPA? https://launchpad.net/~mc3man/+archive/ubuntu/trusty-media To s ...
- 使用NPOI完成导出Excel文件
参考网址:http://blog.csdn.net/tiemufeng1122/article/details/6732588 能够实现 点击按钮弹出下载框 的功能,如图: HTML代码: & ...
- mini6410-JNI-led
一.编写JNI模块 当安装好NDK编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块. 1.在/home/android/文件夹下,新建“ledjni ...
- python学习笔记1
python3.3使用urllib2报错 no module named urllib2,原因是python3中将urllib2换成了request. 所以要使用import urllib.reque ...