POJ1742coins

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xyc1719/article/details/80042739
————————————————
版权声明:本文为CSDN博主「xyc1719」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xyc1719/article/details/80042739

 

我没有想到的是这个题目居然是完全背包的限制

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xyc1719/article/details/80042739
————————————————
版权声明:本文为CSDN博主「xyc1719」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xyc1719/article/details/80042739



我没有想到的是这个题目居然是完全背包的限制

/**
poj 1742  多重背包的可行性问题
题目大意:给定n种面值的硬币面值分别为wi个数为ci,问用这些硬币可以组成1~m之间的多少面值
解题思路:楼教主的男人八题之一,算是一个经典的问题,定义一个sum数组。每次填dp[j]时直接由dp[j-weight[i]]推出,
          前提是sum[j-w[i]]<c[i].sum每填一行都要清零,sum[j]表示当前物品填充j大小的包需要至少使用多少个.复杂度O(n*m)
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <iostream>
using namespace std;

int n,m;
int w[105],c[105],sum[100005],dp[100005];
//w c  直接就是输入的数据, 然后 sum 是对 第I 个物品的使用数量, dp则是标记是否可以达到
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)break;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&w[i]);
        }
        for(int i=0;i<n;i++)
        {
            scanf("%d",&c[i]);
        }
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            memset(sum,0,sizeof(sum));    //一定要注意更新, 以为我们是对sum数组进行循环使用
            for(int j=w[i];j<=m;j++)
            {
                if(!dp[j]&&dp[j-w[i]]&&sum[j-w[i]]<c[i])
                {
                    dp[j]=1;
                    sum[j]=sum[j-w[i]]+1;
                    ans++;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-09-11 11:21  lucky_light  阅读(199)  评论(0编辑  收藏  举报