• 【POJ 1742】Coins【DP】【多重背包】


    题目大意:

    题目链接:http://poj.org/problem?id=1742
    nn种面值不同的硬币,每种有c[i]c[i]个。求1到mm有多少面值可以用这些硬币凑成?


    思路:

    很明显的完全背包。。。
    这里写图片描述
    这里写图片描述
    这里写图片描述
    前面WA,TLE,RE,CEWA,TLE,RE,CE全是用二进制拆分做的。。。后来实在没办法打了书上的方法。
    f[i]f[i]为面值为ii可否得到。那么最基本的O(tnm2)O(tnm^2)肯定是过不了的。需要优化。
    used[i]used[i]表示面值凑到ii的最小硬币使用数,那么我们就可以省掉一重循环,因为,可以用usedused来进行最小答案的判断。
    最终答案为i=1nf[i]\sum^{n}_{i=1}f[i]
    时间复杂度:O(tnm)O(tnm)


    代码:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int n,m,c[101],a[101],used[100001],sum;
    bool f[100001];
    
    int main()
    {
    	while (scanf("%d%d",&n,&m)==2)
    	{
    		if (!n&&!m) return 0;
    		memset(f,0,sizeof(f));
    		memset(c,0,sizeof(c));
    		memset(a,0,sizeof(a));
    		f[0]=true;  //初始化
    		for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    		for (int i=1;i<=n;i++) scanf("%d",&c[i]);
    		for (int i=1;i<=n;i++)
    		{
    			memset(used,0,sizeof(used));  //对于不同的i都要清空。
    			for (int j=a[i];j<=m;j++)
    			 if (used[j-a[i]]<c[i]&&!f[j]&&f[j-a[i]])  
    			 {
    			 	used[j]=used[j-a[i]]+1;  //要多使用一枚硬币
    			 	f[j]=true;
    			 }
    		}
    		sum=0;
    		for (int i=1;i<=m;i++)
    		 sum+=f[i];
    		printf("%d\n",sum);
    	}
    }
    
  • 相关阅读:
    python全局变量与局部变量
    TCP的三次握手四次挥手
    关于Http的面试题
    HSTS
    关于网络安全攻防知识
    http详解
    python中的f''、b''、u''、r''
    常见SQL Server导入导出数据的几个工具
    chrome浏览器中 F12 功能的简单介绍
    Sqlcmd使用详解
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998673.html
Copyright © 2020-2023  润新知