題解 P1450 HAOI2008 硬幣購物

2022-03-06 23:18:36 字數 1431 閱讀 8351

本題想到多重揹包還是很容易的(什麼?不知道多重揹包?)

但是,另一題解已經將時間安排計算地明明白白

所以想到完全揹包(多重揹包跟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 ...