思路:把价值看做体积,而价值的大小还是其本身,那么只需判断1-m中的每个状态最大是否为自己,是就+1;
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #define Maxn 100010 #define Max(a,b) (a)>(b)?(a):(b) using namespace std; int dp[Maxn],num[110],v[110]; struct Que{ int pos,val; }que[Maxn*2]; int main() { int n,m,i,j; while(scanf("%d%d",&n,&m)!=EOF,n&&m) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) scanf("%d",v+i); for(i=1;i<=n;i++) scanf("%d",num+i); int d; int cnt; for(i=1;i<=n;i++) { if(v[i]>m) continue; if(v[i]*num[i]>=m) {for(j=v[i];j<=m;j++) dp[j]=Max(dp[j],dp[j-v[i]]+v[i]); continue;} for(d=0;d<v[i];d++) { int head=1,rear=0; for(j=0;j<=(m-d)/v[i];j++) { while(head<=rear&&que[rear].val<dp[j*v[i]+d]-j*v[i]) rear--; que[++rear].val=dp[j*v[i]+d]-j*v[i],que[rear].pos=j; if(que[head].pos<j-num[i]) head++; dp[j*v[i]+d]=que[head].val+j*v[i]; } } } cnt=0; for(i=1;i<=m;i++) if(dp[i]==i) cnt++; printf("%d ",cnt); } return 0; }