硬幣問題(字典最小序) DAG動態規劃問題

2021-07-10 01:21:40 字數 1615 閱讀 6117



題目:

有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...