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;
    }
    


  • 相关阅读:
    STM32 硬件I2C 到底是不是个坑?
    memory cache 和 disk cache
    希尔排序为什么不稳定
    17-18专业课
    fread和fseek的用法
    浅析alsa声卡驱动snd_interval结构体openmin,openmax和integer含义
    动态存储区、静态存储区、堆和栈的区别
    【专家坐堂Q&A】在 petalinux-config 中选择外部来源时,可将符号链路添加内核来源目录树
    模型文件后缀介绍
    @RestController注解
  • 原文地址:https://www.cnblogs.com/xindoo/p/3595028.html
Copyright © 2011-2022 走看看