P1450 HAOI2008 硬幣購物

2021-09-28 15:29:25 字數 1727 閱讀 8009

完全揹包和容斥原理的結合

可以看乙個區間相減的(其實是錯的,但是好理解

求[ 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的東西有多少種方案(在每種錢都有無限的情況)

f [s

]−∑i

=14f

[s−(

d[i]

+1)∗

c[i]

]f[s]-\sum_^f[s-(d[i]+1)*c[i]]

f[s]−∑

i=14

​f[s

−(d[

i]+1

)∗c[

i]]則表示減去這個區間的情況,也就是在錢有限的情況

但是我們不能直接累加起來然後減掉,我們可以看到f[s

−(d[

i]+1

)∗c[

i]

]f[s-(d[i]+1)*c[i]]

f[s−(d

[i]+

1)∗c

[i]]

這是一種錢的情況,因為有可能第1種物品超過限制的同時,第二種物品數量也超過了限制,如果直接累加會把這種情況計算兩次,顯然是不正確的(即同時兩個硬幣有限制的情況減了兩次)。

注意第一種第二種同時超額、第一種第三種都超額、第一種第四種都超額、第二種第三種都超額、第二種第四種都超額、第三種第四種都超額的方案在上一步中都被減了兩次,所以額外都加一次回來

#include

#define ll long long

#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)

using

namespace std;

const

int maxn=

1e6+10;

const

int maxm=

1e3+10;

ll s,n;

ll ans;

ll d[maxn]

,c[maxn]

,f[maxn]

;template

<

class

t>

inline

void

read

(t &x)

while

(isdigit

(ch)

) x*

=f;}

void

pre_work()

}void

dfs(ll pos,ll sum,ll flag)

dfs(pos+

1,sum,flag)

;dfs

(pos+

1,sum-c[pos]

*(d[pos]+1

),-flag);}

void

readdata()

}int

main()

P1450 HAOI2008 硬幣購物

p1450 haoi2008 硬幣購物 完全揹包 容斥 真是秒呀 方案數統計。如果無法直接計算出來,可以嘗試使用容斥原理進行拼湊。你看,這個題中的對答案有影響的元素只有4個。2 n 次方的容斥完全可以做 我們可以使用所有的方案數,減去乙個硬幣不合法的方案數,加上兩個硬幣不合法的方案數,然後如此搞一搞...

題解 P1450 HAOI2008 硬幣購物

本題想到多重揹包還是很容易的 什麼?不知道多重揹包?但是,另一題解已經將時間安排計算地明明白白 所以想到完全揹包 多重揹包跟01揹包似乎區別不大 可以先預處理完全揹包的情況,然後瞎搞容斥原理 不懂容斥原理的看這裡 傳送門 想到完全揹包和容斥原理後,剩下的就只是打表一些簡單的實現了 上 include...

洛谷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 ...