POJ1742 coins 动态规划之多重部分和问题
原题链接: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 动态规划之多重部分和问题的更多相关文章
- POJ_1742_Coins_(动态规划,多重部分和)
描述 http://poj.org/problem?id=1742 n种不同面额的硬币 ai ,每种各 mi 个,判断可以从这些数字值中选出若干使它们组成的面额恰好为 k 的 k 的个数. 原型: n ...
- 多重部分和 poj1742
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- POJ1742 Coins(男人八题之一)
前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示 ...
- 编程算法 - 多重部分和问题 代码(C)
多重部分和问题 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有n种不同大小的数字a, 每种各m个. 推断能否够从这些数字之中选出若干使它们的 ...
- HDU2844(多重部分和)
Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- COJ 0557 4013多重部分和问题
4013多重部分和问题 难度级别:B: 运行时间限制:2000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 n种大小不同的数字 Ai,每种各Mi个,判断是否可以从 ...
- 题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)
Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...
- DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数
当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...
随机推荐
- 基本SQL查询语句
使用Emp表和Dept表完成下列练习 Emp员工表 empno ename job Mgr Hiredate Sal Comm Deptno 员工号 员工姓名 工作 上级编号 受雇日期 薪金 佣金 部 ...
- shell getopts用法详解
本文链接:https://blog.csdn.net/u012703795/article/details/46124519 获取UNIX类型的选项: unix有一个优点就是标准UNIX命令在执行时都 ...
- JavaWeb(七):EL表达式、自定义标签和JSTL
一.EL表达式 语法 el.jsp <%@page import="java.util.Date"%> <%@page import="com.atgu ...
- linux运维、架构之路-linux定时任务
1.基础优化之开机启动服务优化 使用awk拼接的方式 [root@cache01 ~]# chkconfig |egrep -v "crond|network|sshd|rsyslog|sy ...
- php中substr_compare()区分大小写吗
PHP substr_compare() 函数 定义和用法 substr_compare() 函数从指定的开始位置比较两个字符串. 提示:该函数是二进制安全且选择性地对大小写敏感(区分大小写). 语法 ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 D Merchandise (斜率优化)
Description: The elderly aunts always like to look for bargains and preferential merchandise. Now th ...
- BZOJ 2729: [HNOI2012]排队 排列组合 + 高精度
Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不 ...
- Spring JDBCTemplate 简单使用
Spring JDBCTemplate applicationContext.xml配置 <?xml version="1.0" encoding="UTF-8&q ...
- 牛客 Rabbit的数列 (线段树维护值为x的个数+区间覆盖)
https://ac.nowcoder.com/acm/contest/907/C 链接:https://ac.nowcoder.com/acm/contest/907/C来源:牛客网 题目描述 Ra ...
- This service allows sftp connections only
这是因为该用用户只开通了sftp,ssh被禁了 可以通过别的主机ssh登陆这台机器 app@home:/software>ssh mysftp@192.168.0.1 Authorized on ...