POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )
题意 : 有 n 种面额的硬币,给出各种面额硬币的数量和和面额数,求最多能搭配出几种不超过 m 的金额?
分析 :
这题可用多重背包来解,但这里不讨论这种做法。
如果之前有接触过背包DP的可以自然想到DP数组的定义 ==> dp[i][j] 表示使用前 i 种硬币是否可以凑成面额 j 。
根据这样的定义,则一开始初始化 dp[0][0] = true 最后统计 dp[n][1 ~ m] 为 true 的数量即为答案
状态转移方程为 dp[i][j] |= dp[i-1][ j - k*val[i] ] ( k 表示取 k 个第 i 种硬币、val[i] 表示第 i 种硬币的面额 )
转移方程的意义不难理解,需要考虑当前的 dp[i][j] 可以从哪些状态转移而来,如下
使用第 i 种硬币刚好凑成 j 的值应当为上个状态( dp[i-1][] )合法的 j-val[i]、j-2*val[i]、j-3*val[i]....
故代码应当为一个如下所示的三重循环,但是复杂度较高无法通过这题.....
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
;
];
int num[maxn], val[maxn];
int main(void)
{
int N, C;
&& C==)){
; i<=N; i++) scanf("%d", &val[i]);
; i<=N; i++) scanf("%d", &num[i]);
memset(dp, false, sizeof(dp));
dp[][] = true;
; i<=N; i++){
; j<=C; j++){
; k<=num[i] && k*val[i]<=j; k++){
dp[i][j] |= dp[i-][j-k*val[i]];
}
}
}
printf(, dp[N]+C+, true));
}
;
}
通常使用 dp 数组只记录布尔值是种浪费的做法,一般就去考虑在保证正确性的情况下改变 dp 含义记录更多信息去降低复杂度!
现将 dp 含义改变为 ==> dp[i][j] 表示用前 i 种硬币凑成 j 时第 i 种硬币最多还可以剩多少
挑战书上是直接给出了定义,但是我更乐于探寻这玩意是什么来的? 注:以下都是我自己的想法
想想上面的解法,好像会发现其实如果我当前考虑过 dp[i][j] = true 了,那么 dp[i][j+val[i]]、dp[i][j+2*val[i]]、dp[i][j+3*val[i]]... 应该都为 true
而枚举 j 的顺序也恰好是从小到大,所以必定会枚举到 dp[i][j+val[i]]、dp[i][j+2*val[i]]...,所以何不写成如下这样
; i<=N; i++){
; j<=C; j++){
dp[j] |= dp[j-val[i]];
}
}
运行了样例之后发现这样的做法得出的答案比标准答案更大!为什么?因为这样的做法没有考虑到数量,一种硬币的数量是有限的
所以当 j+k*val[i] 的 k 超过了规定数量的时候就会发生错误,使得一些本该为 false 的 dp 数组值变成了 true,所以我们需要记录数量!

复杂度为 O(n*m) 在 POJ 上跑了 2016MS
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
;
];
int num[maxn], val[maxn];
bool fun(int x)
{ ) return true; return false; }
int main(void)
{
int N, C;
&& C==)){
; i<=N; i++) scanf("%d", &val[i]);
; i<=N; i++) scanf("%d", &num[i]);
memset(dp, -, sizeof(dp));
dp[] = ;
; i<=N; i++){
; j<=C; j++){
) dp[j] = num[i];
) dp[j] = -;
;
}
}
printf(, dp++C, fun));
}
;
}
POJ 1742 Coins ( 经典多重部分和问题 && DP || 多重背包 )的更多相关文章
- poj 1742 Coins(二进制拆分+bitset优化多重背包)
\(Coins\) \(solution:\) 这道题很短,开门见山,很明显的告诉了读者这是一道多重背包.但是这道题的数据范围很不友好,它不允许我们直接将这一题当做01背包去做.于是我们得想一想优化. ...
- hdu 2844 poj 1742 Coins
hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正 ...
- 题解报告:hdu 2844 & poj 1742 Coins(多重部分和问题)
Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. On ...
- poj 1742 Coins(dp之多重背包+多次优化)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- POJ 1742 Coins(多重背包, 单调队列)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- [POJ 1742] Coins 【DP】
题目链接:POJ - 1742 题目大意 现有 n 种不同的硬币,每种的面值为 Vi ,数量为 Ni ,问使用这些硬币共能凑出 [1,m] 范围内的多少种面值. 题目分析 使用一种 O(nm) 的 D ...
- POJ 1742 Coins 【多重背包DP】
题意:有n种面额的硬币.面额.个数分别为A_i.C_i,求最多能搭配出几种不超过m的金额? 思路:dp[j]就是总数为j的价值是否已经有了这种方法,如果现在没有,那么我们就一个个硬币去尝试直到有,这种 ...
- POJ 1742 Coins(多重背包) DP
参考:http://www.hankcs.com/program/cpp/poj-1742-coins.html 题意:给你n种面值的硬币,面值为a1...an,数量分别为c1...cn,求问,在这些 ...
- poj 1742 Coins (多重背包)
http://poj.org/problem?id=1742 n个硬币,面值分别是A1...An,对应的数量分别是C1....Cn.用这些硬币组合起来能得到多少种面值不超过m的方案. 多重背包,不过这 ...
随机推荐
- Matlab 文件格式化/Matlab Source File Formattor
由于需要使用到别人编写的Matlab代码文件,但是呢不同的人有不同的风格,有的写得就比较糟糕了. 为了更好地理解代码的内容,一个比较美观的代码会让人身心愉悦. 但是在网上并没有找到一个比较好的实现,此 ...
- html的标签规范
if/else标签{ % if condition1 %} ... display 1{ % elif conditon2 %} ... display 2{ % else % } ... displ ...
- 20191118 Spring Boot官方文档学习(4.9)
4.9.安全 如果Spring Security在类路径上,则默认情况下Web应用程序是采用的.Spring Boot依靠Spring Security的内容协商策略来确定使用httpBasic还是f ...
- SpringBoot 单元测试junit test
pom引用 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http: ...
- [Web 前端] 023 js 的流程控制、循环和元素的获取、操作
1. Javascript 流程控制 用于"基于不同条件执行不同的动作"的场合 1.1 if 语句 三种形式 // 第一种 if... // 第二种 if... else ... ...
- linux服务器上安装mysql
mysql版本:mysql-5.6.44-linux-glibc2.12-x86_64.tar linux操作系统和版本信息: 1.检查linux服务器上是否已安全mysql [root@localh ...
- Spring框架 课程笔记
Spring框架 课程笔记 第1章 Spring概述 1.1 Spring概述 1) Spring是一个开源框架 2) Spring为简化企业级开发而生,使用Spring ...
- The Frog's Games
The Frog's Games Problem Description The annual Games in frogs' kingdom started again. The most famo ...
- python day1-requests
一.什么是requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库. 相对于urllib库(自带,无需手动安装)而言, ...
- luogu P1232 [NOI2013]树的计数
传送门 这题妙蛙 首先考虑构造出一个合法的树.先重新编号,把bfs序整成\(1,2,3...n\),然后bfs序就是按照从上到下从左往右的遍历顺序,所以可以考虑对bfs序分层,可以知道分层方式只会对应 ...