Problem S

Time Limit : 2000/1000ms (Java/Other)   Memory Limit :32768/32768K (Java/Other)

Total Submission(s) : 12   Accepted Submission(s) : 0

Problem Description

Whuacmers use coins.They havecoins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse andfound there were some coins. He decided to buy a very nice watch in a nearbyshop. He wanted to pay the exact price(without change) and he known the pricewould not more than m.But he didn't know the exact price of thewatch.<br><br>You are to write a program which readsn,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coinsof value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can payuse these coins.

Input

The input contains severaltest cases. The first line of each test case contains two integers n(1 ≤ n ≤100),m(m ≤ 100000).The second line contains 2n integers, denotingA1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test caseis followed by two zeros.

Output

For each test case output theanswer on a single line.

Sample Input

3 10

1 2 4 2 1 1

2 5

1 4 2 1

0 0

Sample Output

8

4

``````//朴素算法
#include <bits/stdc++.h>

using namespace std;

int main()

{

int n,m;

while(scanf("%d%d",&n,&m)&&(n||m))

{

int i,j,k,a[102],c[102],f[100002];

for(i=1;i<=n;i++)

scanf("%d",&a[i]);

for(i=1;i<=n;i++)

scanf("%d",&c[i]);

for(i=0;i<100002;i++)

f[i]=0;

for(i=1;i<=n;i++)

for(j=m;j>=0;j--)

for(k=0;k<=c[i];k++)

if(j>=k*a[i])

f[j]=max(f[j],f[j-k*a[i]]+k*a[i]);

int ans=0;

for(i=1;i<=m;i++)

{

if(f[i]==i])  ans++;

}

printf("%d\n",ans);

}

return 0;

}``````

``````//这种二进制超时
#include <bits/stdc++.h>

using namespace std;

int main()

{

int n,m;

while(~scanf("%d%d",&n,&m)&&(n||m))

{

int a[102],c[102],f[100002],v[100002];

for(int i=0;i<n;i++)

scanf("%d",&a[i]);

for(int i=0;i<n;i++)

scanf("%d",&c[i]);

//二进制优化

int j=0;

for(int i=0;i<n;i++)

{

int t=1;

while(c[i]>=t)

{

j++;

v[j]=a[i]*t;

c[i]-=t;

t*=2;

}

j++;

v[j]=c[i]*a[i];//将c[i]以2为指数的堆：1，2，4.....2的（k-1）次方,c[i]-（2的k次方）+1

}

for(int i=0;i<100002;i++)

f[i]=0;

for(int i=0;i<j;i++)

for(int k=m;k>=v[i];k--)

f[k]=max(f[k],f[k-v[i]]+v[i]);

int ans=0;

for(int i=1;i<=m;i++)

if(f[i]==i)  ans++;

printf("%d\n",ans);

}

return 0;

}``````

``````//这种二进制优化过了
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)&&(n||m))
{
int i,j,k,p,a[105],c[105],f[100005];
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
scanf("%d",&c[i]);

memset(f,0,sizeof(f));
f[0]=1;//初始化
for(i=1;i<=n;i++)
{
k=1;
while(c[i]>=k)//二进制优化
{
p=k*a[i];
for(j=m;j>=p;j--)
if(f[j-p]==1)
f[j]=1;
c[i]-=k;
k*=2;
}
if(c[i])
{
p=a[i]*c[i];
for(j=m;j>=p;j--)
if(f[j-p]==1)
f[j]=1;
}
}
int ans=0;
for(i=1;i<=m;i++)
{
if(f[i]==1)  ans++;
}
printf("%d\n",ans);
}
return 0;
}``````