poj 1742
首先多重揹包有一種普通的二進位制優化,然後這題還可以加乙個判斷如果,a[i] * c[i] >= m 的話,那就和完全揹包一樣,不用多重揹包。這樣應該能過。
第二種做法,是參考了完全揹包,完全揹包可以用o(nm)的複雜度完成,是因為,遍歷m的時候沒有數量的限制。那對於這題多重揹包,就要考慮在dp裡面加上當前物品用掉的數量資訊,從而達到完全揹包的複雜度。所以用dp[i][j] 表示,當前物品i湊出j元錢時,還剩下多少個i物品。
轉移方程也不難寫,全部初始化為-1,如果dp[i][j]已經不為0,說明上一種物品就能配出這個錢,所以dp[i][j] = c[i]。如果上一種配不出,那麼if
(dp[
i][j
−a[i
]]>0)
dp[i
][j]
=dp[
i][j
−a[i
]]−1
i f(
dp[i
][j−
a[i]
]>0)
dp[i
][j]
=dp[
i][j
−a[i
]]−1
說明多用乙個當前物品就能配出這個錢。
仔細一想,第一維是可以優化掉的。
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 110;
const
int maxm = 100100;
int dp[maxm];
int n,m,a[maxn],c[maxn];
int main()
int cnt= 0;
for (int i=1;i<=m;i++) if ( dp[i] != -1 ) cnt++;
printf("%d\n",cnt);
}return
0;}
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 的方法來優化多重揹包,即在列舉體積的時候我們按照完全揹包來順序列舉,完全揹包裡的列舉體積是可以滿足重複選擇同意物品的...