首先直接做多重揹包肯定會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.