题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844
题目翻译:
给出N种硬币,硬币数量不限,求能够组成1~m中数字的个数。
首先硬币有无限个,然后我们求每个容量能否恰好装满,因为
装满才是刚好有硬币能凑成该钱数的情况。
AC代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int N,V;
int value[110],num[110];
int dp[100010];
void ZeroOnePack(int weight,int value) {
for(int i = V; i >= weight; i--) {
dp[i] = max(dp[i],dp[i-weight]+value);
}
}
void MultiplyPack() {
for(int i = 1; i <= N; i++) {
int k = 1;
int ccount = num[i];
while(k <= ccount) {
ZeroOnePack(k*value[i],k*value[i]);
ccount-=k;
k *= 2;
}
ZeroOnePack(ccount*value[i],ccount*value[i]);
}
}
int main() {
while(~scanf("%d%d",&N,&V)) {
if(N==0 && V==0) break;
for(int i = 1; i <= N; i++) {
scanf("%d",&value[i]);
}
for(int i = 1; i <= N; i++) {
scanf("%d",&num[i]);
}
for(int i = 0; i <= V; i++) {
dp[i] = -inf;
}
dp[0] = 0;
MultiplyPack();
int sum = 0;
for(int i = 0; i <= V; i++) {
if(dp[i]>0)
sum++;
}
printf("%d\n",sum);
}
return 0;
}