题意:给了n件物品,每件物品有对应的价值Ai和数量Ci,求1-m价值之间有多少价值能够通过这些物品的价值凑出来 分析:多重背包,因为n很大需要二进制优化 nlogn的复杂度
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 3e6 + 10;
int dp[maxn],v[maxn],c[maxn];
int n,m;
const int INF = 0x3f3f3f3f;
void multibag(int maxx)
{
for(int i = 1; i <= n; i++)
{
int t = c[i],k = 1;
while(k < t)
{
for(int j = maxx; j >= k * v[i]; j--)
{
dp[j] = max(dp[j],dp[j - k * v[i]] + k);
}
t -= k;
k *= 2;
}
for(int j = maxx; j >= t * v[i]; j--)
dp[j] = max(dp[j],dp[j - t * v[i]] + t);
}
}
int main()
{
while(cin>>n>>m)
{
if(n == 0 && m == 0)
break;
for(int i = 1; i <= n; i++)
scanf("%d",&v[i]);
for(int i = 1; i <= n; i++)
scanf("%d",&c[i]);
for(int i = 0; i <= m; i++)
dp[i] = -INF;
dp[0] = 0;
multibag(m);
// for(int i = 1; i <= m; i++)
// {
// multibag(i);
// }
int ans = 0;
for(int i = 0; i <= m; i++)
{
if(dp[i] > 0)
ans++;
}
cout<<ans<<endl;
}
return 0;
}