硬币问题——固定终点的最长路和最短路
生活随笔
收集整理的這篇文章主要介紹了
硬币问题——固定终点的最长路和最短路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題描述:
?? ??? 有n種硬幣,面值分別為V1,V2...,Vn,每種都有無限多。給定非負整數S,可以選用多少個硬幣,使得面值之和恰好為S?輸出硬幣數目的最小值和最大值。0 <= n <= 100, 0 <= S <= 10000, 1 <= Vi <= S。
分析:
?? ??? 本題的本質還是DAG上的路徑問題。我們把每種面值看作一個點,表示"還需要湊足的面值",則初始狀態為S,目標狀態為0。若當前的狀態i,每使用一個硬幣j,狀態便轉移到i-Vj。這個模型和嵌套矩形一題類似,但也有些明顯的不同之處:嵌套矩形中并沒有確定路徑的起點和終點(可以把任意矩形放在第一個和最后一個),而本題的起點必須是S,終點必須是0。把終點固定之后"最短路"才是有意義的。在嵌套矩形中,最短序列顯然是空(如果不允許空的話,就是單個矩形,不管怎樣都是平凡的),而本題的最短路徑卻不是那么容易確定的。
?????? 接下來考慮"硬幣問題"。注意到最長路和最短路的求法是類似的,下面只考慮最長路。由于終點固定,d(i)的確切含義變為"從節點i出發到節點0的最長路徑長度"。
下面是求最長路的代碼(錯誤的):
int dp(int S)//錯誤 {int& ans=d[S];if(ans>=0) return ans;ans=0;for(int i=1;i<=n;i++)if(S>=V[i])ans=max(ans,dp(S-V[i])+1);return ans; } /*此代碼有一個致命的錯誤,即由于節點S不一定真的能到達節點0,所以需要用特殊的d[S]值表 示"無法到達",但在上述代碼中,如果S根本無法繼續往前走,返回值是0,將被誤以為是"不能 走已經到達終點"的意思。*/
正確的解法一:
正確的解法二:
????? 本題要求最小、最大兩個值,記憶化搜索就必須寫兩個。在這種情況下,還是遞推來得更加方便(此時需注意遞推的順序):
完整代碼:
總結
以上是生活随笔為你收集整理的硬币问题——固定终点的最长路和最短路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《楚乔传》宇文玥的父亲竟是柱国大将军 他
- 下一篇: PL/SQL Developer跑在Or