#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int val[1000],num[1200],qwe[101000];
long long dp[110908];
int main()
{
int n,m,ans,s,i,j;
while(scanf("%d%d",&n,&m)&&(n+m))
{
ans=0;
for(i=0;i<n;i++)
{
scanf("%d",&val[i] );
}
for(i=0;i<n;i++)
{
scanf("%d",&num[i] );
}
memset(qwe,0,sizeof(qwe));
qwe[0]=1;
for(i=0;i<n;i++)
{ memset(dp,0,sizeof(dp));//注意一下,这个就体现了多重,数组dp用来记录每次遍历的次数
for(j=val[i];j<=m;j++)
{
if(!qwe[j]&&qwe[j-val[i]]&&dp[j-val[i]]+1<=num[i])//其他的没有改变,这就体现了相互选与不选的影响
//其实我是不太理解的,我是把这些都列举了出来,才发现这样写确实可以,如果用多重背包的模板写会超时。
{
qwe[j]=1;dp[j]=dp[j-val[i]]+1;ans++;
}
}
}
printf("%d\n",ans);
}
return 0;
}
给出硬币面额及每种硬币的个数,求从1到m能凑出面额的个数。
Input
多组数据,每组数据前两个数字为n,m。n表示硬币种类数,m为最大面额,之后前n个数为每种硬币的面额,后n个数为相应每种硬币的个数。 (n<=100,m<=100000,面额<=100000,每种个数<=1000)
Output
RT
Sample Input
3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
Sample Output
8 4