题意:购买手表,有N种硬币和总价值为M的手表。第i种硬币最多有c[i]个,每个价值是a[i]。用硬币购买手臂,总和不超过手表总价值,且价值总和最大
思路:多重背包,定义数组dp[],然后判断dp[i]==1是否成立,即能否组合成不超过M的任意一个数,如果可以计数加1.
感想:比较典型的多重背包,还是要掌握好多重背包的基础合理转化。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
int i,j,k,n,m,a[101],c[101],dp[100001],num,count;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
scanf("%d",&c[i]);
memset(dp,0,sizeof(dp));
dp[0]=1;
for(i=0;i<n;i++)
for(j=0;j<a[i];j++)
{
count=c[i];
for(k=j+a[i];k<=m;k+=a[i])
if(dp[k]==1) count=c[i];
else if(count>0&&dp[k-a[i]]==1)
{
dp[k]=1;
count--;
}
}
num=0;
for(i=1;i<=m;i++)
if(dp[i]==1)
num++;
printf("%d\n",num);
}
return 0;
}