POJ 1742Coins 多重背包转完全背包

题意:有n种硬币,给出每种硬币的面值和个数,问这些硬币能组成多少种小于m的面值。

 

状态化的多重背包,二进制拆01背包超时,教主本意是要用单调队列来做,不过由于时间限制比较宽松所以可以转完全背包来做。

想法就是新建一个数组来存每种状态中用了多少个第 i 种硬币,在用第 i 种硬币更新状态时,同时更新这个记录数组。

 

代码如下:

#include<stdio.h>
#include<string.h>

int bag[100005],used[100005],worth[105],amount[105];

int main()
{
    int n,m,i,j,cnt;
    while(scanf("%d%d",&n,&m),n||m)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&worth[i]);
        for(i=1;i<=n;i++)
            scanf("%d",&amount[i]);
        memset(bag,0,sizeof(bag));
        bag[0]=1;
        cnt=0;
        for(i=1;i<=n;i++)
        {
            memset(used,0,sizeof(used));
            for(j=worth[i];j<=m;j++)
            {
                if(!bag[j]&&bag[j-worth[i]]&&used[j-worth[i]]+1<=amount[i])
                {
                    bag[j]=1;
                    used[j]=used[j-worth[i]]+1;
                    cnt++;
                }
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}
posted @ 2014-03-04 17:10  zhen94  阅读(137)  评论(0编辑  收藏  举报