題目:
有n種硬幣,面值分別為v1,v2,...vn,每種都有無限多。給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?輸出硬幣數目的最小值和最大值!
分析:我們把每種面值看作乙個點!表示「還需要湊足的面值」,初始狀態為s,目標狀態為0。那麼若當前狀態在i,每使用乙個硬幣j,狀態便轉移到i-vj
因為求最大值跟求最小值類似,這裡只貼記憶化搜尋求最小值**
**: 下面dp1跟dp2功能相同。
不同dp2好理解一些。通過設定陣列vis,標識是否訪問過。犧牲空間換取效率,易讀性。
#include"stdio.h"
#include"stdlib.h"
#include"algorithm"
#include"string.h"
#include"math.h"
using namespace std;
const int inf=1e9;
const int max_coin=105;
const int max_s=10005;
int coin[max_coin];
int d[max_s];
int vis[max_s];
int n;
//d(i) 從節點i出發到節點0的最長路徑
int dp1(int s)
ans=ans==inf?0:ans;
return ans;
}int dp2(int s) //犧牲空間換效率,容易理解
int main()
for(int i=0;i=coin[i]&&d[s]==d[s-coin[i]]+1)
} int main()
memset(max_path,0,sizeof(max_path));
memset(min_path,0,sizeof(min_path));
for(int i=1;i<=n;i++)
for(int j=coin[i];j<=s;j++)
}}void print_ans(int *d,int s)
} int main()
這裡補充乙個問題:
n元錢換為零錢,有多少不同的換法?幣值包括1 2 5分,1 2 5角,1 2 5 10 20 50 100元。
例如:5分錢換為零錢,有以下4種換法:
1、5個1分
2、1個2分3個1分
3、2個2分1個1分
4、1個5分
(由於結果可能會很大,輸出mod 10^9 + 7的結果)
#include"stdio.h"
#include"stdlib.h"
#include"algorithm"
#include"string.h"
#include"math.h"
int coin[14]=;
const int maxn=1e5+5;
const int mod=1e9+7;
int dp[maxn];//dp[i][j]表示前i種貨幣能夠湊齊j錢組合數
int main()
DAG之硬幣問題DP(最長路及其字典序)
問題描述 有n種硬幣,面值分別為v1,v2,v3,vn,每種都有無限多。給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?輸出硬幣數目的最小值和最大值。1 n 100,0 s 10000,1 vi s.分析與思路 思路 本題是固定終點和起點的dag動態規劃。我們把每種面值看做乙個點,表示 還...
動態規劃 DAG模型 硬幣問題
題目 有n種硬幣,面值分別為v1,v2,vn,每種都有無限多。給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?輸出硬幣數目的最小值和最大值!dag問題的動態規劃求解 includeusing namespace std typedef long long ll typedef long d...
DAG上的動態規劃 硬幣問題
題目 有n種硬幣,面值分別為v1,v2,vn,每種都有無限多。給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?輸出硬幣數目的最小值和最大值!分析 我們把每種面值看作乙個點!表示 還需要湊足的面值 初始狀態為s,目標狀態為0。那麼若當前狀態在i,每使用乙個硬幣j,狀態便轉移到i vj。inc...