poj 1742 Coins

来源:互联网 发布:如何使用网络电视 编辑:程序博客网 时间:2024/05/17 20:26

题意:有n种面额的硬币,面额个数分别为A_i、C_i,求最多能搭配出几种不超过m的金额?

分析:1.想到类似于完全背包,只是每个物品数量有限制

  2.看到搭配出的钱数有最大上限,可以将其变成数组索引;

  3.类似于完全背包的转移,不过每次转移需要记录用过多少金币,或者还剩多少

  4.dp[i][j]表示第i种金币,搭配出j块钱还剩多少数量的硬币,其中dp值为负代表无法搭配出这个数目的金钱




#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXM 100010#define MAXN 105bool vis[MAXM];int dp[MAXM],val[MAXN],num[MAXN];int main(){    int n,m;    while(scanf("%d%d",&n,&m),n | m)    {        for(int i = 1;i <= n;i++)            scanf("%d",&val[i]);        for(int i = 1;i <= n;i++)            scanf("%d",&num[i]);        memset(dp,0,sizeof(dp));        memset(vis,0,sizeof(vis));        vis[0] = dp[0] = 1;        int ans = 0;        for(int i = 1;i <= n;i++)        {            for(int j = 0;j <= m;j++)            {                if(dp[j] <= 0 && j >= val[i])                    dp[j] = dp[j - val[i]] - 1;                else if(dp[j] > 0)                    dp[j] = num[i] + 1;                if(dp[j] > 0 && !vis[j])                    vis[j] = ++ans;            }        }        printf("%d\n",ans);    }}


0 0