日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVA 11259 Coin Changing Again

發(fā)布時(shí)間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVA 11259 Coin Changing Again 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意:有4種硬幣,面值分別為c1,c2,c3,c4,然后給出Q組查詢。每組查詢給出5個(gè)數(shù)d1,d2,d3,d4,v,分別表示面值為ci的硬幣共有di個(gè),然后要求將其湊成總值為v的方案數(shù)。

數(shù)據(jù)范圍大致是c<=1000,Q<=100,d,v<=100000。

如果按照普通分組背包的做法,對每組Q都做一遍DP,那么這個(gè)復(fù)雜度就會(huì)達(dá)到10^9的級別,肯定會(huì)TLE。我也拿不出太好的辦法,覺得這題DP不出來。

其實(shí),這題不完全是DP,我覺得這個(gè)題目的核心是容斥原理。對于每組查詢,算法的復(fù)雜度基本上是O(1)這樣的常數(shù)級的。

在UVA的論壇里看到了大牛的解釋:

假設(shè)現(xiàn)在只有兩種硬幣,我們令N=所有湊出v總值的方案數(shù),N1=第一種面值為c1的硬幣取了超過d1次湊出總值v的方案數(shù),N2=第二種面值為c2的硬幣取了超過d2次湊出總值v的方案數(shù),N12=第一種面值為c1的硬幣取了超過d1次且N第二種面值為c2的硬幣取了超過d2次湊出總值v的方案數(shù)。那么對于一組查詢d1,d2,v,合法的方案數(shù)就是N-N1-N2+N12.

為了計(jì)算這些N,我們利用c1,c2,c3,c4先做一遍背包容量為100000的無限背包,用dp數(shù)組記錄方案數(shù)。

那么計(jì)算N的話,直接算用dp[v]就可以了。

怎么計(jì)算N1呢?因?yàn)閏1硬幣取了超過了d1次,那么我們就假設(shè)它取了d1+1次,共取走了(d1+1)*c1價(jià)值的硬幣,那么方案數(shù)就是dp[v-(d1+1)*c1]。

同理,N2的方案數(shù)就是dp[v-(d2+1)*c2],N12的方案數(shù)就是dp[v-(d1+1)*c1-(d2+1)*c2]。然后統(tǒng)計(jì)N-N1-N2+N12,就可以得到答案了。

現(xiàn)在問題中的硬幣種類邊成了4個(gè),還是用一樣的原理,這時(shí)候答案就是N-N1-N2-N3-N4+N12+N13+N14+N23+N24+N34-N123-N124-N134-N234+N1234,一共16項(xiàng)。

1 #include <cstdio> 2 typedef long long LL; 3 LL dp[100010]; 4 5 int main(){ 6 int c[4],d[4],v,Q,kase; 7 scanf("%d",&kase); 8 while(kase--){ 9 dp[0] = 1; 10 for(int i = 1;i <= 100000;i++) dp[i] = 0; 11 12 for(int i = 0;i < 4;i++) 13 scanf("%d",&c[i]); 14 15 for(int i = 0;i < 4;i++) 16 for(int j = c[i];j <= 100000;j++) 17 dp[j] += dp[j-c[i]]; 18 19 scanf("%d",&Q); 20 21 while(Q--){ 22 LL ans = 0; 23 24 for(int i = 0;i < 4;i++) 25 scanf("%d",&d[i]); 26 27 scanf("%d",&v); 28 29 for(int i = 0;i < 16;i++){ 30 int tmp = v; 31 int flag = 1; 32 for(int j = 0;j < 4;j++){ 33 if(i&(1<<j)){ 34 flag = -flag; 35 tmp -= (d[j]+1) * c[j]; 36 } 37 } 38 if(tmp >= 0) ans += flag * dp[tmp]; 39 } 40 41 printf("%lld\n",ans); 42 } 43 } 44 return 0; 45 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/zhexipinnong/p/3420455.html

總結(jié)

以上是生活随笔為你收集整理的UVA 11259 Coin Changing Again的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。