poj 1742 多重背包问题 dp算法

题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种

思路:多重背包问题

dp[i][j]表示用前i种硬币组成j最多剩下多少个  dp=-1的表示凑不齐

dp[0][0]=0;

for(int i=0;i<n;i++)

    for(int j=0;j<=m;j++)

{    if(dp[i][j]>=0)   dp[i+1][j]=c[i];  //表示用前i种可以凑齐j元,自然就全部剩下了

      else if(j<a[i]||dp[i+1][j-a[i]]<=0) dp[i+1][j]=-1;  //表示没法凑

      else dp[i+1][j]=dp[i+1][j-a[i]]-1;   //表示用了i这种硬币

}

如何数组重用呢?

dp[j]表示前i种硬币(循环)凑成j元最多剩下

dp[0]=0;

for(int i=0;i<n;i++)

for(int j=0;j<=m);j++)

{if(dp[j]>=0) dp[j]=c[i];

else if(j<a[i]||dp[j-a[i]]<=0) dp[j]=-1;

else dp[j]=dp[j-a[i]]-1;}

解决问题的代码:

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
int a[116];
int c[116];
int dp[100000 + 16];
int main()
{
        int n,m;
        while (scanf("%d%d", &n, &m) != EOF)
        {
               if (n == 0 && m == 0) break;
               for (int i = 0; i < n; i++)
                       scanf("%d", &a[i]);
               for (int i = 0; i < n; i++)
                       scanf("%d", &c[i]);
               memset(dp, -1, sizeof(dp));
               dp[0] = 0;
               for(int i=0;i<n;i++)
                       for (int j = 0; j <= m; j++)
                       {
                              if (dp[j] >= 0) dp[j] = c[i];
                              else if (j < a[i] || dp[j - a[i]] <= 0) dp[j] = -1;
                              else dp[j] = dp[j - a[i]] - 1;
                       }
               int ans = 0;
               for (int i = 1; i <= m; i++)
               {
                       if (dp[i] >= 0) ++ans;
               }
               printf("%d\n", ans);
        }
        return 0;
}

原文地址:https://www.cnblogs.com/xuxiaojin/p/9406830.html

时间: 2024-10-12 18:06:00

poj 1742 多重背包问题 dp算法的相关文章

poj 1742 Coins(dp之多重背包+多次优化)

Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact pri

[POJ 1742] Coins 【DP】

题目链接:POJ - 1742 题目大意 现有 n 种不同的硬币,每种的面值为 Vi ,数量为 Ni ,问使用这些硬币共能凑出 [1,m] 范围内的多少种面值. 题目分析 使用一种 O(nm) 的 DP (据说这是类多重背包?),枚举每一种硬币,对于每一种硬币 i 枚举每一个面值 j ,如果这个面值 j 使用前 i-1 种硬币已经可以凑出,就直接跳过,否则尝试加入一个硬币 i ,看是否能凑出 j .需要满足 (f[j - Vi] == true) && (UseNum[j - Vi] +

HDU 2844 Coins (多重背包问题DP)

题意:给定n种硬币,每种价值是a,数量是c,让你求不大于给定V的不同的价值数,就是说让你用这些硬币来组成多少种不同的价格,并且价格不大于V. 析:一看就应该知道是一个动态规划的背包问题,只不过是变形,那我们就统计不大于V的不同价格数,也容易实现, 对于多重背包我们是把它转化为01背包和完全背包来解决的. 代码如下: #include <cstdio> #include <iostream> #include <cstring> using namespace std;

Coins (poj 1742 &amp;&amp; hdu 2844 DP)

Language: Default Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 30047   Accepted: 10195 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and fou

POJ 1742 Coins (多重背包)

Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 28448   Accepted: 9645 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some

poj 1742 Coins 多重背包变形

传说中的男人八题,是男人就A这八题.有n种面额的硬币,面额个数分别为A_i.C_i,求最多能搭配出几种不超过m的金额? 这是一个多重部分和问题(多重背包问题),放在了<2.3 记录结果再利用的"动态规划" 优化递推关系式>.最基本的做法是: dp[i][j] := 用前i种硬币能否凑成j 递推关系式: dp[i][j] = (存在k使得dp[i - 1][j - k * A[i]]为真,0 <= k <= m 且下标合法) 然后三重循环ijk递推 1 2 3 4

POJ 1742 Coins 多重背包单调队列优化

http://poj.org/problem?id=1742 题意: 很多硬币,有价值和数量,给出一个上限,问上限内有多少种钱数可以由这些硬币组成. 分析: 好像是楼教主男人八题之一.然后学多重背包单调队列优化时看了别人的程序..所以后来写了就1A了=.= 前一篇小小总结了一下多重背包单调队列优化(http://www.cnblogs.com/james47/p/3894772.html),这里就不写了. 1 #include<cstdio> 2 #include<cstring>

poj 1742 Coins (动态规划,背包问题)

Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 32977   Accepted: 11208 Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some

hdu 2844 poj 1742 Coins

hdu 2844 poj 1742 Coins 题目相同,但是时限不同,原本上面的多重背包我初始化为0,f[0] = 1;用位或进行优化,f[i]=1表示可以兑成i,0表示不能. 在poj上运行时间正好为时限3000ms....太慢了,hdu直接TLE(时限1s); 之 后发现其实并不是算法的问题,而是库函数的效率没有关注到.我是使用fill()按量初始化的,但是由于memset()可能是系统底层使用了四个字节拷 贝的函数(远比循环初始化快),效率要高得多..这就是为什么一直TLE的原因,fil