本題想到多重揹包還是很容易的(什麼?不知道多重揹包?)
但是,另一題解已經將時間安排計算地明明白白
所以想到完全揹包(多重揹包跟01揹包似乎區別不大)
可以先預處理完全揹包的情況,然後瞎搞容斥原理
不懂容斥原理的看這裡:傳送門
想到完全揹包和容斥原理後,剩下的就只是打表一些簡單的實現了
上**
#includeusing namespace std;
long long c[5],d[5],dp[100010],tot,s;
long long q(long long x)//便於打表
int main()
cin>>tot;
dp[0]=1;//初始化,之後預處理
for(int i=1;i<=4;i++) }
for(int js=1;js<=tot;js++)
cin>>s;
long long ans=dp[s];//初始,之後容斥原理**
if(s>=q(1))
ans-=dp[s-q(1)];
if(s>=q(2))
ans-=dp[s-q(2)];
if(s>=q(3))
ans-=dp[s-q(3)];
if(s>=q(4))
ans-=dp[s-q(4)];
if(s>=q(1)+q(2))
ans+=dp[s-q(1)-q(2)];
if(s>=q(1)+q(3))
ans+=dp[s-q(1)-q(3)];
if(s>=q(1)+q(4))
ans+=dp[s-q(1)-q(4)];
if(s>=q(2)+q(3))
ans+=dp[s-q(2)-q(3)];
if(s>=q(2)+q(4))
ans+=dp[s-q(2)-q(4)];
if(s>=q(3)+q(4))
ans+=dp[s-q(3)-q(4)];
if(s>=q(1)+q(2)+q(3))
ans-=dp[s-q(1)-q(2)-q(3)];
if(s>=q(1)+q(2)+q(4))
ans-=dp[s-q(1)-q(2)-q(4)];
if(s>=q(1)+q(3)+q(4))
ans-=dp[s-q(1)-q(3)-q(4)];
if(s>=q(2)+q(3)+q(4))
ans-=dp[s-q(2)-q(3)-q(4)];
if(s>=q(1)+q(2)+q(3)+q(4))
ans+=dp[s-q(1)-q(2)-q(3)-q(4)];//個人認為這個表打得相當美觀~
cout<}}
P1450 HAOI2008 硬幣購物
完全揹包和容斥原理的結合 可以看乙個區間相減的 其實是錯的,但是好理解 求 2,3 2,3 2,3 轉換為求 2,3,2,3 begin 2,infty 3,infty rightarrow 2,3 end 2,3 2,3 f s f s f s 表示買s ss的東西有多少種方案 在每種錢都有無限的...
P1450 HAOI2008 硬幣購物
p1450 haoi2008 硬幣購物 完全揹包 容斥 真是秒呀 方案數統計。如果無法直接計算出來,可以嘗試使用容斥原理進行拼湊。你看,這個題中的對答案有影響的元素只有4個。2 n 次方的容斥完全可以做 我們可以使用所有的方案數,減去乙個硬幣不合法的方案數,加上兩個硬幣不合法的方案數,然後如此搞一搞...
洛谷P1450 HAOI2008 硬幣購物
硬幣購物一共有4種硬幣。面值分別為c1,c2,c3,c4。某人去商店買東西,去了tot次。每次帶di枚ci硬幣,買si的價值的東西。請問每次有多少種付款方法。輸入格式 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s 輸出格式 每次的方法數 輸入樣例 1 1 2 5 ...