zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        
        return 0;
    }
  • 相关阅读:
    PBN飞越转弯Flyover衔接DF航段保护区组图
    子群
    点集拓扑
    近世代数总结
    windows目标进程注入dll
    api文档方法参数
    windows制作动态链接库和使用二
    windows制作动态链接库和使用一
    拷贝构造函数
    c++内联函数
  • 原文地址:https://www.cnblogs.com/demian/p/7355600.html
Copyright © 2011-2022 走看看