原题链接:http://poj.org/problem?id=1742

题目大意:tony现在有n种硬币,第i种硬币的面值为A[i],数量为C[i]。现在tony要使用这些硬币去买一块价格不超过m的表。他希望买的时候不用找零,问有多少种价格能满足这一点。

这个问题实际上是一个多重部分和的问题:假设有n种物品,每种物品的价值为v[i],数量为c[i],随意选取这些物品,能否使它们的价值之和恰好为m。使用动态规划的思想来求解这类问题:

定义dp数组,dp[i][j]的值代表前i种物品随意选取,价值之和为j时第i种物品最多能剩下多少个,当前i种物品无法使价值之和刚好为j时,其值为-1。那么,很明显,递推关系存在四种情况:

①:如果dp[i - 1][j] >= 0,也就是说前i - 1种物品已经可以组合得到j,此时第i种物品可以一件也不取,即dp[i][j] = c[i];

②:如果不满足情况①,那么我们要通过在第i种物品中选取来使价值之和为j,但如果j的值小于v[i]的话,哪怕只选取一个也会超过j,所以此时无法实现要求,dp[i][j] = -1;

③:如果不满足情况①且j又不小于v[i]时,也许我们可以通过选取a个第i种物品来使价值之和恰好为j(1 <= a)。如果可以的话,那么选取a - 1个一定可以使价值之和为j - v[i],所以dp[i][j]可以由dp[i][j - v[i]]推出。如果dp[i][j - v[i]]等于-1(无法实现)或者等于0(第i种物品已用完),dp[i][j]都等于-1;

④:在情况③中,如果在第i种中拿a个能使价值之和为j - v[i],且第i种物品还有剩余,那再拿一个就可以使价值之和为j了,即dp[i][j] = dp[i][j - v[i]] - 1。

有了这些递推关系,我们就可以用如下的代码来求解多重部分和问题:

int n;//物品种数
int m;//目标和
int v[n];//每种物品的价值
int c[n];//每种物品的数量
memset(dp, -, sizeof(dp));
dp[] = ;//初始化
for(int i = ;i < n;i++)
{
for(int j = ;j <= m;j++)
{
if(dp[j] >= )//情况①
{
dp[j] = c[i];
//这里滚动使用了一个一维数组,dp[j]在更新前代表的是上一轮的值(即二维的dp[i - 1][j])或初始值
}
else if(j < v[i] || dp[j - v[i]] <= )//情况②、③
{
dp[j] = -;
}
else//情况④
{
dp[j] = dp[j - v[i]] - ;
}
}
}

这道poj1742只是在上面这个问题的基础上略加变形,我们只需要遍历dp数组求出1-m中有多少中价格可以被组合出来即可得到答案。

不过这种解法在POJ上耗时1800ms左右,虽然可以ac,但可能无法应付更大的数据规模或者更高的效率要求,我们还可以借助二进制优化或者各种数据结构来进一步提高效率。

POJ1742 coins 动态规划之多重部分和问题的更多相关文章

  1. POJ_1742_Coins_(动态规划,多重部分和)

    描述 http://poj.org/problem?id=1742 n种不同面额的硬币 ai ,每种各 mi 个,判断可以从这些数字值中选出若干使它们组成的面额恰好为 k 的 k 的个数. 原型: n ...

  2. 多重部分和 poj1742

    Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...

  3. 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)

    Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...

  4. POJ1742 Coins(男人八题之一)

    前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示 ...

  5. 编程算法 - 多重部分和问题 代码(C)

    多重部分和问题 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有n种不同大小的数字a, 每种各m个. 推断能否够从这些数字之中选出若干使它们的 ...

  6. HDU2844(多重部分和)

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. COJ 0557 4013多重部分和问题

    4013多重部分和问题 难度级别:B: 运行时间限制:2000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 n种大小不同的数字 Ai,每种各Mi个,判断是否可以从 ...

  8. 题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  9. DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数

    当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...

随机推荐

  1. HTML导航框架实现

    导航栏界面(html_contents.html) <!DOCTYPE html> <html> <head> <meta charset=” utf-8” ...

  2. 使用myBase Desktop来管理电脑上的资料

    下载链接:下载链接:http://www.wjjsoft.com/download.html 选择自己的操作系统下的myBase Desktop 这里是下载的是安装包,有解压的版本的. 这里就简单介绍 ...

  3. Python基础入门一文通 | Python2 与Python3及VSCode下载和安装、PyCharm激活与安装、Python在线IDE、Python视频教程

    目录 1. 关键词 2. 推荐阅读 2.1. 视频教程 3. 本文按 4. 安装 4.1. 视频教程 4.2. 资源下载 4.3. 安装教程 1. 关键词 Python2 与Python3及VSCod ...

  4. linux精简开机启动服务

    1.可以使用 setup-system services 里面调整,这样调整起来效率低 2.或者 ntsysv 调出来 3.使用脚本一件关闭 #LANG=en chkconfig --list #停止 ...

  5. sqlmap POST注入

    带表单的页面: 1.sqlmap.py -u "http://mysqli/Less-11/" --forms 2.python sqlmap.py -r d:\test.txt ...

  6. Spring如何解决循环依赖问题

    目录 1. 什么是循环依赖? 2. 怎么检测是否存在循环依赖 3. Spring怎么解决循环依赖 本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可 ...

  7. 外媒:Apple面临着印度iPhone的停用

    据外媒报道:印度电信管理局(TRAI)制定遏制令人讨厌的消息的新规则可能导致印度数百万部iPhone的停用. 该监管机构本周早些时候宣布了“2018年电信商业通信客户偏好规定”,根据该规定,它已提议“ ...

  8. tuple写法

    name = ("wen") 类型为strname = ("wen",) 类型为tuple

  9. Python---基础-小游戏用户猜数字

    一.10 < cost < 50 的等价表达式 cost = 40 10 < cost < 50 (10 < cost) and (cost < 50) 二.使用i ...

  10. Ubuntu系统安装两个tomcat

    1:创建两个tomcat 2:在/etc下有个 profile 然后vim 编辑它 在 最下面加上这句话.这是两个tomcat的路径 #开启多个tomcat export CATALINA_BASE ...