zoukankan      html  css  js  c++  java
  • poj 1742 Coins (多重背包)

    题意很简单, 有n种硬币,每种硬币面额多大,有多少个,求可以构成m以内的面额有多少种。

    开始用的是普通的多重背包的求法,裸裸的超时了,看了别人的代码,发现可以优化很多。

    用usea这个来存储用来多少个a硬币,避免的很多无用的计算。

    先贴以前超时的代码

    #include <stdio.h>
    #include <string.h>
    
    int dp[100005];
    int coin[101];
    int cnt[101];
    int used[1000101];
    
    int main()
    {
        int n, k;
        while(scanf("%d %d", &n, &k))
        {
            if (n==0 && k==0)
                break;
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", &coin[i]);
            }
            for (int j = 1; j <= n; j++)
            {
                scanf("%d", &cnt[j]);
            }
            memset(dp, 0, sizeof(dp));
            dp[0] = 1;
            int ans = 0;
            for (int i = 1; i <= n; i++)
            {
                memset(used, 0, sizeof(used));
                for (int j = coin[i]; j <= k; j++)
                {
                    if (!dp[j] && dp[j-coin[i]] && used[j-coin[i]] < cnt[i])
                    {
                        ans++;
                        used[j]=used[j-coin[i]]+1;
                        dp[j] = 1;
                    }
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }


    下面是A了的代码

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    
    int a[105];
    int c[105];
    bool canpay[100005];
    int usea[100005];
    int main()
    {
        int n, m;
        while (scanf("%d %d", &n, &m) && (m||n))
        {
            memset(canpay, 0, sizeof(canpay));
            for (int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            for (int i = 1; i <= n; i++)
                scanf("%d", &c[i]);
            int ans = 0;
            canpay[0] = true;
            for (int i = 1; i <= n; i++)
            {
                memset(usea, 0, sizeof(usea));
                for (int j = a[i]; j <= m; j++)
                {
                    if (!canpay[j] && canpay[j-a[i]] && usea[j - a[i]] < c[i])
                    {
                        ans += 1;
                        canpay[j] = true;
                        usea[j] = usea[j - a[i]] + 1;
                    }
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    


  • 相关阅读:
    Python札记 装饰器
    Python与SQLite日期时间函数的使用
    Python札记 文件校验
    Python札记 参数魔法
    JAVA操作图片裁切与缩放的一个工具类
    java对象的序列化和反序列化
    Apache MINA 初识
    在Java 7里如何对文件进行操作
    Calendar时间获取明细
    使用ViewPager实现欢迎页面左右拖动效果
  • 原文地址:https://www.cnblogs.com/xindoo/p/3595028.html
Copyright © 2011-2022 走看看