題意:
有n種硬幣,每種的價值為a(i),數量為c(i)
問任意組合這些硬幣,能組合出1到m中的多少種**
資料範圍:n<=100,m<=1e5,a(i)<=1e5,c(i)<=1e3
解法:
容易想到令d[i]
[j]表示前i種硬幣能否組成j,可以用滾動陣列忽略掉第一維陣列空間
但是如果直接計數的話複雜度為o
(n*m*max
),肯定不行呀
從其他地方學到了乙個新操作:
用d[j]表示當前能否組成j
假設當前列舉到第i種硬幣,
令cnt[j]表示當前組成j所需要使用的這種硬幣的最少數量
先將cnt清空為0
從a[i]到m列舉j,如果d[j]
==0且d[j-a[i]]==
1,意味著使用乙個a[i]可以從d[j-a[i]
]轉移到d[j]
但是需要判斷硬幣數量是否足夠
如果cnt[j-a[i]]+
1<=c[i]則足夠,此時d[j]=1
,cnt[j]
=cnt[j-c[i]]+
1妙啊
code:#include
using
namespace std;
const
int maxm=
1e5+5;
int a[maxm]
,c[maxm]
;int cnt[maxm]
;//cnt[i]表示當前組成i必須用掉多少個硬幣
int d[maxm]
;//d[i]表示能否組成i
signed
main()
}}int ans=0;
for(
int i=
1;i<=m;i++
)printf
("%d\n"
,ans);}
return0;
}
poj 1742 Coins 多重揹包
題意很簡單,有n種硬幣,每種硬幣面額多大,有多少個,求可以構成m以內的面額有多少種。開始用的是普通的多重揹包的求法,裸裸的超時了,看了別人的 發現可以優化很多。用usea這個來儲存用來多少個a硬幣,避免的很多無用的計算。先貼以前超時的 include include int dp 100005 in...
POJ 1742 Coins 多重揹包DP
題意 有n種面額的硬幣。面額 個數分別為a i c i,求最多能搭配出幾種不超過m的金額?思路 dp j 就是總數為j的價值是否已經有了這種方法,如果現在沒有,那麼我們就乙個個硬幣去嘗試直到有,這種價值方法有了的話,那麼就是總方法數加1。多重揹包可行性問題 傳統多重揹包三重迴圈會超時,因為只考慮是否...
poj1742 Coins 多重揹包優化DP
給定n個物品,第i個物品價值為a i 數量為c i 求可以組成的小於m的價值的個數。好像n,m的範圍比較大,暴力跑二進位制優化的多重揹包是可以卡過去的。但是有一種o nm o n m 的方法來優化多重揹包,即在列舉體積的時候我們按照完全揹包來順序列舉,完全揹包裡的列舉體積是可以滿足重複選擇同意物品的...