poj 1742 Coins(dp)

来源:互联网 发布:sql数据仓库培训 编辑:程序博客网 时间:2024/05/17 23:00

题目链接

Coins
Time Limit: 3000MS Memory Limit: 30000KTotal Submissions: 29601 Accepted: 10031

Description

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 101 2 4 2 1 12 51 4 2 10 0

Sample Output

84

题意:有n个价值为a1,a2....an的硬币,每种硬币的数目分别为c1,c2....cn。求用这些硬币能恰好支付的1-m的价格有多少种?

题解:本问题是个多重背包问题,用多重背包O(NV)的解法可做。其实这题还有更简单的方法,复杂度为O(VN)。

用dp[i][j] 表示前i种硬币恰好支付价值j后,第i种硬币最多剩多少个?

初始化dp初值为-1,表示前i种硬币不能恰好支付价格j。

转移就是:

if(dp[i-1][j]>=0)//不用第i种硬币

dp[i][j]=c[i];

 else if(j-a[i]>=0&&dp[i][j-a[i]]>0)//用第i种硬币
dp[i][j]=dp[i][j-a[i]]-1;

代码如下:

#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>#include<string>#include<queue>#include<stack>#include<map>#include<set>#include<stdlib.h>#include<vector>#define inff 0x3fffffff#define nn 110000#define mod 1000000007typedef long long LL;const LL inf64=inff*(LL)inff;using namespace std;int n,m;int a[nn],c[nn];int dp[2][nn];int main(){    int i,j;    while(scanf("%d%d",&n,&m)&&(n+m))    {        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        for(i=1;i<=n;i++)        {            scanf("%d",&c[i]);        }        memset(dp,-1,sizeof(dp));        dp[0][0]=0;        int t=1;        for(i=1;i<=n;i++)        {            for(j=0;j<=m;j++)            {                if(dp[1-t][j]>=0)                    dp[t][j]=c[i];                else if(j-a[i]>=0&&dp[t][j-a[i]]>0)                    dp[t][j]=dp[t][j-a[i]]-1;            }            t=1-t;            for(j=0;j<=m;j++)            {                dp[t][j]=-1;            }        }        int ans=0;        for(j=1;j<=m;j++)        {            if(dp[1-t][j]>=0)                ans++;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击