题意:给你一些不同价值和一定数量的硬币,求用这些硬币可以组合成价值在[1 , m]之间的有多少;
思路:由于考虑时间,所以需要用二进制优化;
#include<stdio.h>
#include<string.h>
#define max(x,y) (x>y?x:y)
int a[101],b[101],dp[100001];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),n||m)
{
int i,j,k,s,temp,st,
ss=0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
int t=1;s=0;st=0;
scanf("%d",&k);
if(k*a[i]>=m)
for(j=a[i];j<=m;j++)
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);//完全背包
else//01背包
{
s+=k*a[i];
while(t<=k)
{
temp=t*a[i];
k=k-t;
st+=t*a[i];
t*=2;
for(j=m;j>=temp;j--)
dp[j]=max(dp[j],dp[j-temp]+temp);
}
if(st<s)
{
temp=s-st;
for(j=m;j>=temp;j--)
dp[j]=max(dp[j],dp[j-temp]+temp);
}
}
}
for(i=1;i<=m;i++)
if(i==dp[i])
ss++;
printf("%d\n",ss);
}
}