POJ 1742 Coins 多重背包DP

Posted Point

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1742 Coins 多重背包DP相关的知识,希望对你有一定的参考价值。

题意:有n种面额的硬币。面额、个数分别为A_i、C_i,求最多能搭配出几种不超过m的金额?

思路:dp[j]就是总数为j的价值是否已经有了这种方法,如果现在没有,那么我们就一个个硬币去尝试直到有,这种价值方法有了的话,那么就是总方法数加1。多重背包可行性问题

传统多重背包三重循环会超时,因为只考虑是否可行,没有考虑剩余面额数量的因素。

o(n*v)方法

#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;

int dp[100005]; //表示当前i价格是否出现过
int sum[100005];//当价格达到i时,最多使用这一种硬币的次数
int v[105],c[105];

int main()
{
    int i,j,n,m;
    while(~scanf("%d%d",&n,&m),n+m)
    {
        for(i = 1;i<=n;i++)
            scanf("%d",&v[i]);
        for(i = 1;i<=n;i++)
            scanf("%d",&c[i]);
        memset(dp,0,sizeof(dp));
        dp[0] = 1;
        int ans = 0;
        for(i=1;i<=n;i++)
        {
            memset(sum,0,sizeof(sum));//关键是用sum来限定了次数
            for(j = v[i];j<=m;j++)//循环检查看是否能够出现前边没有出现的价格
            {
                if(!dp[j] && dp[j-v[i]] && sum[j-v[i]]<c[i])
				{ //如果j价格没有出现过,且j-v[i]出现过,并且使用i硬币的次数没有超出给定的数量
                    dp[j] = 1;
                    sum[j] = sum[j-v[i]]+1;//使用次数+1
                    ans++;
                }
            }
        }
        printf("%d\n",ans);
    }
    
    return 0;
}

以上是关于POJ 1742 Coins 多重背包DP的主要内容,如果未能解决你的问题,请参考以下文章

poj1742 Coins多重背包贪心

POJ1742 Coins(男人八题之一)

POJ1742 Coins 多重背包+贪心

poj1742 Coins(多重背包+单调队列优化)

Coins POJ - 1742 (背包判断可行性)

poj 1742 多重背包问题 dp算法