日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法导论一分治法

發布時間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法导论一分治法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

分治法的實“力”

  • 歸并排序
  • 乘方問題(斐波那契數列)
    • 遞歸
    • 自下而上的遞歸
    • 矩陣的n次冪

最近閑了點開始肝算法導論了,先介紹一些可能貫穿在整個算法導論文章的一些思想。

首先是T(n)用來表示需要的時間,我們往往研究三種情況的T(n)。第一種是最壞情況(worst),用大佬的話說就是給用戶一個保證,保證不管輸入的數據時間復雜度不會比這個更差了,比如你說這個程序至多運行三秒,這個沒有問題但如果你說是至少運行三秒,那它會不會運行三年呢,這不是一個可靠的保證。第二種平均(average),簡單來說就是期望,或者更嚴格來說是加權的,但是我們怎么知道概率是多少呢,這就需要一些假設了。第三種情況是最好(best),我常常覺得這是tricky或者bogus,因為這種情況是基本不會發生的。

接下來介紹主定理方法,這是在遞歸中我們確定時間復雜度的方法。設T(n)=aT(n/b)+f(n).
case 1:當f(n)=O(nlogba-t),則T(n)=O(nlogba
case 2:當f(n)=O(nlogba),則T(n)=O(nlogbalogn)

歸并排序

#include <iostream> #include <vector>using namespace std;void merge(vector<int>& arr, int L, int mid, int R) {//int* help = new int(R - L + 1);std::vector<int>help(R - L + 1);int p1 = L, p2 = mid + 1, i = 0;while (p1 <= mid && p2 <= R){help[i++] = arr[p1] > arr[p2] ? arr[p2++] : arr[p1++];}while (p1 <= mid)help[i++] = arr[p1++];while (p2 <= R)help[i++] = arr[p2++];for (int i = 0; i < R - L + 1; i++){arr[L + i] = help[i];} } void MergeSort(vector<int>& arr, int L, int R) {if (L < R){int mid = L + ((R - L) >> 2); // (L+R)/2MergeSort(arr, L, mid);MergeSort(arr, mid + 1, R);merge(arr, L, mid, R);} }int main() {vector<int> arr;int n, temp;cin >> n; //輸入n個數for (int i = 0; i < n; i++){cin >> temp; //輸入數據arr.push_back(temp);}MergeSort(arr, 0, arr.size() - 1);for (int i = 0; i < arr.size(); i++)cout << arr[i] << endl;system("pause");return 0;}

乘方問題(斐波那契數列)

遞歸

這是樸素算法,可以利用斐波那契數列的數學表達式進行遞歸func2(n - 1) + func2(n - 2),很顯然即便不經過數學計算,直覺告訴這個算法運行的時間非常長,是指數級別的,這里給出具體的時間復雜度O(αn)其中α=(1+5\sqrt{5}5?)/2

int func2(int n) {if (n <= 2) return 1;else returnfunc2(n - 1) + func2(n - 2); }

自下而上的遞歸

上面的遞歸做了非常多無用功與重復計算,計算第n個數時第n-1個數已經計算出來了就不需要再計算了。

int func1(int n,int x,int y) {if (--n)return func1(n, y, x + y);elsereturn x + y; }

矩陣的n次冪

本來還有一種方法叫平方遞歸式但是比較難用算法表示出來,所以直接來看矩陣n次冪法,這里運用了斐波那契數列的性質(Fn+1,Fn,Fn,Fn-1)=(1,1,1,0)n

而計算n次冪則完全可以用分支的思想實現快速冪,比如xn=xn/2xn/2時間復雜度就降下來了。

#include<iostream> #include<time.h> using namespace std;struct Mat {int m[2][2]; };int func1(int n,int x,int y) {if (--n)return func1(n, y, x + y);elsereturn x + y; }int func2(int n) {if (n <= 2) return 1;else returnfunc2(n - 1) + func2(n - 2); }Mat mul(Mat a, Mat b) {Mat c;c.m[0][0] = 0;c.m[0][1] = 0;c.m[1][0] = 0;c.m[1][1] = 0;for (int i = 0; i < 2; i++)for (int j = 0; j < 2; j++)for (int k = 0; k < 2; k++)c.m[i][j] += a.m[i][k] * b.m[k][j];return c; }Mat init() {Mat a;for (int i = 0; i < 2; i++) {for (int j = 0; j < 2; j++) {a.m[i][j] = 1;}}return a; }int func3(int n) {Mat res;Mat base;res.m[0][0] = 1;res.m[0][1] = 0;res.m[1][0] = 0;res.m[1][1] = 1;base.m[0][0] = 1;base.m[0][1] = 1;base.m[1][0] = 1;base.m[1][1] = 0;while (n != 0) {if (n & 1) {res = mul(res, base);}base = mul(base, base);n >>= 1;}return res.m[0][1]; }int main() {int n = 30000;clock_t start;clock_t end;//while (n > 2) {start = clock();//cout<<func1(n - 2, 0, 1)<<endl;//cout << func2(n -1) << endl;cout << func3(n-1) << endl;//Mat res = func3(n-1);//for (int i = 0; i < 2; i++)// for (int j = 0; j < 2; j++)// cout << res.m[i][j];end = clock();cout << n << " " << (double)(end - start)/CLOCKS_PER_SEC << endl;//n--;//} }

總結

以上是生活随笔為你收集整理的算法导论一分治法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。