POJ 1742 Coins 揹包dp變形

2021-08-22 13:41:54 字數 1079 閱讀 4067

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 的方法來優化多重揹包,即在列舉體積的時候我們按照完全揹包來順序列舉,完全揹包裡的列舉體積是可以滿足重複選擇同意物品的...