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;
}