POJ 1742 Coins 【多重背包DP】
阿新 • • 發佈:2017-08-14
數量 printf can 硬幣 ring editable urn content std
題意:有n種面額的硬幣。面額、個數分別為A_i、C_i,求最多能搭配出幾種不超過m的金額?
思路:dp[j]就是總數為j的價值是否已經有了這種方法,如果現在沒有,那麽我們就一個個硬幣去嘗試直到有,這種價值方法有了的話,那麽就是總方法數加1。多重背包可行性問題
傳統多重背包三重循環會超時,因為只考慮是否可行,沒有考慮剩余面額數量的因素。
o(n*v)方法
#include <iostream> #include <cstdio> #include <string.h> #include <string> #include <algorithm> using namespace std; int dp[100005]; //表示當前i價格是否出現過 int sum[100005];//當價格達到i時,最多使用這一種硬幣的次數 int v[105],c[105]; int main() { int i,j,n,m; while(~scanf("%d%d",&n,&m),n+m) { for(i = 1;i<=n;i++) scanf("%d",&v[i]); for(i = 1;i<=n;i++) scanf("%d",&c[i]); memset(dp,0,sizeof(dp)); dp[0] = 1; int ans = 0; for(i=1;i<=n;i++) { memset(sum,0,sizeof(sum));//關鍵是用sum來限定了次數 for(j = v[i];j<=m;j++)//循環檢查看是否能夠出現前邊沒有出現的價格 { if(!dp[j] && dp[j-v[i]] && sum[j-v[i]]<c[i]) { //如果j價格沒有出現過,且j-v[i]出現過,並且使用i硬幣的次數沒有超出給定的數量 dp[j] = 1; sum[j] = sum[j-v[i]]+1;//使用次數+1 ans++; } } } printf("%d\n",ans); } return 0; }
POJ 1742 Coins 【多重背包DP】