遞推,遞迴,貪心,列舉思想
轉載自:http://www.cnblogs.com/huangxincheng/category/340148.html
· 演算法 (真正的程式設計應該是:程式設計=XX語言+資料結構+演算法)
· 遞推思想
· 概念:通過已知條件,利用特定關係逐步遞推,最終得到結果為止,核心就是不斷的利用現有資訊推匯出新的東西。
· 分類:“順推”,“逆推”
· “順推”是指通過條件推出結果
· “逆推”是指通過結果推出條件
· 例子:“斐波那契”數列,銀行取錢
#region 遞推思想
/// <summary>
/// 斐波那契數列
/// </summary>
public static void Fibonacci()
{
int month = 12;
int[] fab = new int[month];
fab[0] = 1;
fab[1] = 1;
for (int i = 2; i < month; i++)
{
fab[i] = fab[i - 1] + fab[i - 2];
}
for (int i = 0; i < fab.Length; i++)
{
Console.WriteLine($"第{i + 1}個月的小兔子為:{fab[i]}");
}
}
/// <summary>
/// 一個富二代給他兒子的四年大學生活存一筆錢,富三代每月只能取3k作為下個月的生活費,採用的是整存零取的方式,
/// 年利率在1.71%,請問富二代需要一次性存入多少錢。
/// 思路: 這個題目是我們知道了結果,需要逆推條件, 第48月富三代要連本帶息的把3k一把取走,那麼
/// 第47月存款應為: (第48個月的存款+3000)/(1+0.0171/12(月));
/// 第46月存款應為: (第47個月的存款+3000)/(1+0.0171/12(月));
/// ..... .....
/// 第1個月存款應為: (第2個月的存款+3000)/(1+0.0171/12(月));
/// </summary>
public static void Fun3()
{
double[] money = new double[48];
money[47] = 3000;
double rate = 0.0171;
for (int i = 46; i >= 0; i--)
{
money[i] = (money[i + 1] + 3000) / (1 + rate / 12);
}
for (int i = 47; i >= 0; i--)
{
Console.WriteLine($"第{i+1}個月的合計為:{money[i]}");
}
}
#endregion
· 遞迴思想
· 概念:遞迴,說白了就是直接或者間接的呼叫自己的一種演算法。它是把求解問題轉化為規模較小的子問題,然後通過多次遞迴一直到可以得出結果的最小解,然後通過最小解逐層向上返回撥用,最終得到整個問題的解。總之遞迴可以概括為一句話就是:“能進則進,不進則退”。
· 三要素:
· 遞迴中每次迴圈都必須使問題規模有所縮小。
· 遞迴操作的每兩步都是有緊密的聯絡,如在“遞迴”的“歸操作時”,前一次的輸出就是後一次的輸入。
· 當子問題的規模足夠小時,必須能夠直接求出該規模問題的解,其實也就是必須要有結束遞迴的條件。
· 注意事項:
· 深層次的遞迴會涉及到頻繁進棧出棧和分配記憶體空間,所以執行效率比較低,當問題規模較大時,不推薦使用。
· 在遞迴過程中,每次呼叫中的引數,方法返回點,區域性變數都是存放在堆疊中的,如果當問題規模非常大時,容易造成堆疊溢位。
· 例子:階乘,十進位制轉二進位制
#region 遞迴思想
/// <summary>
/// 求階乘
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public static int Fact(int n)
{
if (n == 1)
{
return 1;
}
return n * Fact(n - 1);
}
/// <summary>
/// 十進位制轉二進位制
/// </summary>
/// <param name="rtn"></param>
/// <param name="num"></param>
/// <returns></returns>
public static string Convert10To2(ref string rtn, int num)
{
if (num == 0)
return string.Empty;
Convert10To2(ref rtn, num / 2);
return rtn += num % 2;
}
#endregion
· 貪心思想
· 貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解。
· 注意事項:
· 不能保證貪心所得出的解是整體最優的。
· 不能用來求最大解和最小解問題。
· 只能求滿足某些約束條件的可行解的範圍。
· 例子:揹包問題,找零錢
#region 貪心思想
/// <summary>
/// 貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。
/// 也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解。
/// </summary>
public static Dictionary<decimal,int> ExChange(decimal num)
{
/*
其實說到貪心,基本上都會提到“揹包問題”,這裡我就舉一個“找零錢的問題“,對的,找零錢問題是我們生活中一個活生生的貪心演算法
的例子,比如我買了“康師傅來一桶方便麵”,給了10兩銀子,方便麵3.8兩,那麼收銀mm該找我6.2兩,現實中mm不自覺的就會用到貪心的行
為給我找最少張幣,總不能我給mm一張,mm給我十幾張,那樣mm會心疼的。
*/
var money = GetInit();
int i = 0;
while(true)
{
if(num < 0.05M)
{
return money;
}
var max = money.Keys.ElementAt(i);//表示100元紙幣
if(num >= max)
{
money[max] = money[max] + 1;
num = num - max;
}
else
{
if (num >= 0.05M && num < 0.1M)
{
money[0.1M] = money[0.1M] + 1;
num = 0.0M;
if (money[0.1M] * 0.1M + money[0.2M] * 0.2M + money[0.5M] * 0.5M == 1.0M)
{
money[0.1M] = 0;
money[0.2M] = 0;
money[0.5M] = 0;
money[1.0M] += 1;
}
}
else
{
i++;
}
}
}
}
static Dictionary<decimal, int> GetInit()
{
Dictionary<decimal, int> money = new Dictionary<decimal, int>();
//key表示錢,value表示錢的張數
money.Add(100.00M, 0);
money.Add(50.00M, 0);
money.Add(20.00M, 0);
money.Add(10.00M, 0);
money.Add(5.00M, 0);
money.Add(2.00M, 0);
money.Add(1.00M, 0);
money.Add(0.50M, 0);
money.Add(0.20M, 0);
money.Add(0.10M, 0);
return money;
}
#endregion
· 列舉思想
· 將問題的所有可能的答案一一列舉,然後根據條件判斷此答案是否合適,保留合適的,捨棄不合適的。
· 列舉是我們在無奈之後的最後一擊,那麼使用列舉時我們應該儘量遵守下面的兩個條件:
· 1.地球人都不能給我找出此問題的潛在規律。
· 2.候選答案的集合是一個計算機必須能夠承受的。
/// <summary>
/// 百錢百雞演算法(用100元錢買100只雞,其中公雞5元一隻,母雞3元一隻,小雞3只1元)
/// Math.DivRem(int a, int b, out int result);返回a/b的餘數,result接收餘數
/// </summary>
public static void Fun2()
{
int a = 0, b = 0, c = 0, p = 0;
for (a = 1; a <= 19; a++)
{
for (b = 1; b <= 33; b++)
{
c = 100 - a - b;
Math.DivRem(c, 3, out p);
if(((5 * a + 3 * b + c / 3) == 100) && p == 0)
{
Console.WriteLine($"a:{a}");
Console.WriteLine($"b:{b}");
Console.WriteLine($"c:{c}");
return;
}
}
}
}
相關文章
- 演算法基礎 - 列舉/遞迴/動歸/深廣搜/二分/貪心演算法遞迴
- SQL 遞迴思想SQL遞迴
- 遞迴實現指數型列舉遞迴
- 遞迴和遞推總結遞迴
- 青蛙跳臺階(遞迴思想)遞迴
- 遞迴思想的巧妙理解遞迴
- Luogu P4425 轉盤 題解 [ 黑 ] [ 線段樹 ] [ 貪心 ] [ 遞迴 ]遞迴
- 10-17 c遞迴與遞推初識遞迴
- 遞迴和尾遞迴遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- 【遞迴】小q的數列遞迴
- 遞迴遞迴
- go 遞迴Go遞迴
- JavaScript遞迴JavaScript遞迴
- 理解遞迴遞迴
- 分而治之-遞迴遞迴
- 『無為則無心』Python函式 — 32、遞迴Python函式遞迴
- 什麼是遞迴?遞迴和迴圈的異同遞迴
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 迭代與遞迴--你被遞迴搞暈過嗎?遞迴
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- 一道遞迴陣列面試題遞迴陣列面試題
- 遞迴總結遞迴
- 遞迴函式遞迴函式
- 談談遞迴遞迴
- 遞迴問題遞迴
- 遞迴加回溯遞迴
- 遞迴-*快速排序遞迴排序
- 遞迴小記遞迴
- 理解遞迴 Recurtion遞迴
- C#遞迴C#遞迴
- sql server遞迴SQLServer遞迴
- Vue元件遞迴Vue元件遞迴
- 馬踏棋盤演算法(騎士周遊問題)----遞迴與貪心優化演算法演算法遞迴優化
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- kingbase SQL最佳化案例 ( union遞迴 改 cte遞迴 )SQL遞迴
- 快速排序(遞迴及非遞迴演算法原始碼)排序遞迴演算法原始碼
- 徹底理解遞迴,從遞迴的本質說起!遞迴