目录:
题目:
分析:
设
f[i]
f
[
i
]
为面值为
i
i
可否得到。那么最基本的肯定是过不了的。需要优化。
设
w[i]
w
[
i
]
表示面值凑到
i
i
的最小硬币使用数,那么我们就可以省掉一重循环,因为,可以用来进行最小答案的判断。
最终答案为
∑Ni=1f[i]
∑
i
=
1
N
f
[
i
]
时间复杂度:
O(tnm)
O
(
t
n
m
)
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int a[101],c[101];
bool f[100001];int w[100001];
int main()
{
int n=read(),m=read();
while(n&&m)
{
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) c[i]=read();
for(int i=1;i<=n;i++)
{
memset(w,0,sizeof(w));
for(int j=a[i];j<=m;j++)
if(!f[j]&&f[j-a[i]]&& w[j-a[i]]<c[i])
f[j]=1,w[j]=w[j-a[i]]+1;
}
int ans=0;
for(int i=1;i<=m;i++) ans+=f[i];
printf("%d\n",ans);
n=read();m=read();
}
return 0;
}