【POJ - 1742】Coins (多重背包)

Coins

直接翻译了

Descriptions

给出硬币面额及每种硬币的个数,求从1到m能凑出面额的个数。 

Input

多组数据,每组数据前两个数字为n,m。n表示硬币种类数,m为最大面额,之后前n个数为每种硬币的面额,后n个数为相应每种硬币的个数。 (n<=100,m<=100000,面额<=100000,每种个数<=1000)

Output

对于每个测试用例,在单行上输出答案。

Sample Input

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

Sample Output

8
4

题目链接

https://vjudge.net/problem/POJ-1742

 

设d[i][j]——前i种硬币,凑成总值j时,第i种硬币所剩余的个数。

   默认d[i][j] = -1,代表无法凑成总值j

   转移方程为,若d[i-1][j]≥0,代表前i-1种已能够凑成j,那么就不必花费第i种硬币,所以d[i][j] = c[i]

   否则就看d[i][j-v[i]]的值,显然如果j < v[i],那么d[i][j] = -1,否则d[i][j-a[i]] ≤ 0,代表此刻第i种硬币已使用完了,所以自然d[i][j] = -1;

   否则,d[i][j] = d[i][j-v[i]]-1;

 

AC代码

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>1
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x,y) memset(x,y,sizeof(x))
#define Maxn 1000005
using namespace std;
int n,m;
int dp[Maxn];
int v[Maxn];
int c[Maxn];
bool cmp(int x)
{
    return x>=0;
}
int main()
{
    while(cin>>n>>m,n+m)
    {
        for(int i=0; i<n; i++)
            cin>>v[i];
        for(int i=0; i<n; i++)
            cin>>c[i];
        MEM(dp,-1);
        dp[0]=0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<=m; j++)
            {
                if(dp[j]>=0)
                    dp[j]=c[i];
                else if(j<v[i]||dp[j-v[i]]<=0)
                    dp[j]=-1;
                else
                    dp[j]=dp[j-v[i]]-1;
            }
        }
        cout<<count_if(dp+1,dp+1+m,cmp)<<endl;//搜索dp数组中大于等于0的个数
    }
    return 0;
}

 

posted on 2019-08-12 16:33  Sky丨Star  阅读(650)  评论(0编辑  收藏  举报

导航