/*
【問題描述】
有n種硬幣,面值分別為v1,v2,v3,.....vn,每種都有無限多。
給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?
輸出硬幣數目的最小值和最大值。1<=n>=100, 0<=s<=10000,1<=vi<=s.
【分析與思路】
思路:本題是固定終點和起點的dag動態規劃。
我們把每種面值看做乙個點,表示「還需要湊足的面值」,則初始狀態為s,目標狀態為0。
如當前在狀態i,沒使用乙個硬幣j,狀態變轉移到i-vj。
有n種硬幣,面值分別為v1,v2,v3,.....vn,每種都有無限多。
給定非負整數s,可以選用多少個硬幣,使得面值之和恰好為s?
輸出硬幣數目的最小值和最大值。1<=n>=100, 0<=s<=10000,1<=vi<=s.
本題是固定終點和起點的dag動態規劃。
我們把每種面值看做乙個點,表示「還需要湊足的面值」,則初始狀態為s,目標狀態為0。
如當前在狀態i,沒使用乙個硬幣j,狀態變轉移到i-vj。 */
遞推方法實現
#include#include#define max 10001
#define inf 1000000000;
int n, s;
int v[max] ,vis[max], d[max];
int max[max], min[max] ;
// 輸出最小字典序
void prit_ans(int *d, int s)
}// 主函式、遞推實現最短路最長路
int main ()
// 遞推演算法求解最長最短路
for (i=1; i<=s; i++)///初始化min初始化為最大值,max初始化為最小值
for (i=1; i <= s; i++)///表示的錢數
for (j=1; j<=n; j++)///對應的個數
if(i >= v[j])///當需要表示的錢幣數大於硬幣所能表示的數值時,才可以往下進行
printf("%d %d\n", min[s], max[s]);
// 輸出最優字典序
prit_ans(min, s);
printf("\n");
prit_ans(max, s) ;
printf("\n");
return 0 ;
}
記憶化搜尋方法實現。裡面加標記的地方為輸出字典序最小的序列
#include #include #include #include using namespace std;
struct data
a[1010];
int g[1010][1010];
int dp[1010];
int n;
int d(int i)
/*void print_ans(int i)}*/
int main()
}cout << maxx << endl;
//print_ans(k);
}return 0;
}
Tarjan演算法縮點 DAG最長路 DP
我們按照複雜程度來討論不同的tarjan演算法變形的差異.但此時只是有所區分的將所有的點劃分為乙個個的強連通分量,尚且沒有縮點.上面這個功能實現起來最簡單.它的tarjan函式內 的.void tarjan int u else if in stack v 還剩下一種不在棧中但是已經訪問過的情況,是...
DAG最長路(最短路)
dag就是有向無環圖。dag上的最長或者最短路是很重要的一類問題。很多問題都可以轉化為dag上的最長或者最短路徑的問題。dag求最短和最長路的方法一樣。本演算法主要解決2個問題 1 求整個dag中的最長路徑 即不固定起點,也不固定終點 2 固定終點,求dag的最長路徑。dp i 表示從i 號頂點出發...
動態規劃四(DAG最長路)
在圖的有關知識中已經了解了dag就是有向無環圖,其中計算最長路 關鍵路徑 的做法非常複雜,這裡介紹更簡單的方法。求整個dag的最長路徑 即不固定起點和終點 固定終點,求dag的最長路徑。給定乙個有向無環圖,怎樣求解整個圖的所有路徑中權值之和最大的那條。令dp i 表示從i號頂點出發能獲得的最長路徑長...