首先直接做多重揹包肯定會TLE的,
觀察這個揹包問題有什麼特殊性呢
物品種類和重量,價值是一定的,不同的是揹包的容量和物品的數量
由於當物品數量沒有限制的時候,方案數是可以預處理出來的
所以我們考慮用ans=物品數量沒有限制時的方案數-物品超出限制的方案數來解決
第一部分是可以用完全揹包來解決的
第二問不難想到用容斥原理來解決
設f[m]為容量為m時的方案數
假如當i號物品超出數量s[i]限制(不知道其他物品有沒有超),方案數f[m-w[i]*(s[i]+1)](嚴格超出限制
以此類推,可得出多個物品超出限制的方案數
根據容斥原理,計算一下即可
var f:array[..] of int64;
w:array[..] of longint;
c:array[..,..] of longint;
t:array[..] of longint;
i,n,j,k,p,y,m,s:longint;
ans:int64; begin
for i:= to do
read(w[i]);
readln(n);
for i:= to n do
begin
for j:= to do
read(c[i,j]);
readln(t[i]);
if t[i]>m then m:=t[i];
end;
f[]:=;
for i:= to do
for j:=w[i] to do
f[j]:=f[j]+f[j-w[i]]; for i:= to n do
begin
ans:=;
for j:= to do //用二進位制表示物品是否超出限制
begin
s:=t[i];
y:=;
for k:= to do
begin
p:= shl (k-);
if j and p<> then
begin
s:=s-w[k]*(c[i,k]+);
if s< then break;
inc(y);
end;
end;
if s< then continue; //注意可能不存在某幾個物品都超出限制的情況
if y mod = then ans:=ans-f[s] else ans:=ans+f[s];
end;
writeln(ans);
end;
end.