B - Coins POJ - 1742

B - Coins

 POJ - 1742 

People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.
You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.

Input

The input contains several test cases. The first line of each test case contains two integers n(1<=n<=100),m(m<=100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000). The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0

Sample Output

8
4

题目描述:

给你n种面值的硬币,面值为a,数量分别为c,这些硬币能组成的在1到m范围内的总面值有多少种。

分析:

  dp[ i ] [ j ]表示前i种硬币组成总面值为j后剩下i种硬币多少个。比如到下一种面值的关系式为dp[ i ] [ j+a[i] ] -1,就是选了一个第i种的硬币,面值到达j+a[i],那么剩下的硬币就应该减1。减到0表示硬币用完了,不能再减了。同时用-1表示不能达到的状态。

  到推下一种硬币,因为非-1的表示在选完上一种后可以到达的面值。所以从这里开始选该种硬币。这里开始就表明该种硬币还没选,就把他的值赋为c[i]。

  关于dp数组的初始化,因为上面都不选的时候面值为0,那么就可以从j=0开始。dp数组也可以转为一维求解。

代码:

 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int a[106];
int c[106];
int main()
{
    while(true)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        if(n==0&&m==0) break;
        int dp[m+6];
        memset(dp,false,sizeof(dp));
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c[i]);
        }
        //初始化第一种硬币的情况 
        for(int i=0;i<m;i++) dp[i]=-1;
        dp[0]=c[1];
        for(int j=a[1];j<=m;j++)
        {
            if(dp[j-a[1]]>=1)
            dp[j]=max(dp[j],dp[j-a[1]]-1);
            else 
            dp[j]=-1;
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                if(dp[j]!=-1) dp[j]=c[i];
                if(j>=a[i])
                {
                    if(dp[j-a[i]]>=1)
                    //max时为了保留数组结果 
                    dp[j]=max(dp[j],dp[j-a[i]]-1);
    
                }
            }    
        }
        int res=m;
        for(int i=1;i<=m;i++)
        {
            if(dp[i]==-1) res--;
        }
        printf("%d\n",res);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/studyshare777/p/12309391.html