本文索引目錄:
1、PTA實驗報告題1 : 程序存儲問題ios
1.1 實踐題目c++
1.2 問題描述算法
1.3 算法描述函數
1.4 算法時間及空間複雜度分析spa
2、PTA實驗報告題2 : 刪數問題3d
2.1 實踐題目code
2.2 問題描述blog
2.3 算法描述排序
2.4 算法時間及空間複雜度分析索引
3、PTA實驗報告題3 : 最優合併問題
3.1 實踐題目
3.2 問題描述
3.3 算法描述
3.4 算法時間及空間複雜度分析
4、實驗心得體會(實踐收穫及疑惑)
題意是,題幹給定磁盤總容量和各個文件的佔用空間,詢問該磁盤最多能裝幾個文件。
簽到題,只須要將各個文件從小到大排序,並拿一個變量存儲已佔用的容量總和,進行對比便可獲得結果。
#include<bits/stdc++.h> #include<algorithm> using namespace std; #define MAXLENGTH 1000 int interger[MAXLENGTH]; int main() { int num,length; int sum = 0; int counter = 0; int m = 0; cin>>num>>length; for(int i=0;i<num;i++){ cin>>interger[i]; } sort(interger,interger+num); while(true){ if(sum+interger[m]>length||counter==num) break; sum+=interger[m]; counter++; m++; } cout<<counter<<endl; return 0; }
總體算法上看,輸入須要O(n)的時間進行輸入,最快用O(nlogn)的時間複雜度進行排序,使用O(n)的時間進行結果疊加,總時間複雜度爲O(nlogn),時間複雜度花費在排序上。
空間上,只須要一個臨時變量存儲當前佔用容量總和便可。
第二題題意是指,在給定的數字串以及可刪數個數的條件下,刪數指定k個數,獲得的數是最小的。
首先,分析題目,刪數問題,能夠用一個比較方便的函數,String類的erase函數,這個函數能夠刪除字符串內的單個或多個字符,能夠比較方便的處理刪數問題。
第二,咱們注意到這道題有個坑點,那就是前導零,咱們須要注意100000,刪除1後結果應爲0
第三,肯定咱們的貪心策略:噹噹前的數,比後一位數大時,刪去當前的數。
如:樣例178543
用一個index時刻從頭日後掃,不知足就後移。
當知足以後,刪除當前的值。
獲得17543,這時將index從新置0,並記錄已刪數+1,直到知足最大刪數。以此類推,直接輸出string即是結果。
AC代碼:
#include<iostream> #include<algorithm> #include<string> using namespace std; #define MAXLENGTH 1005 int main(){ int k; string a; cin>>a>>k; int len = a.size(); while(k>0){ for(int i = 0;(i<a.size()-1);i++){ if(a[i]>a[i+1]) { a.erase(i,1); break; } } k--; } while(a.size()>1&&a[0]=='0'){ a.erase(0,1); } cout<<a<<endl; return 0; }
時間複雜度爲O(n^2),即開銷在不斷的刪數和回溯到字符串頭的過程。
空間複雜度須要一個String字符串長度,所以空間複雜度是O(n)
該題目爲:題目用 2 路合併算法將這k 個序列合併成一個序列,而且合併 2 個長度分別爲m和n的序列須要m+n-1 次比較,輸出某段合併的最大比較次數和最小比較次數。
這道題算是哈夫曼算法的一道裸題,很容易解決,只須要使用優秀隊列不斷維護最小值或最大值便可。
哈夫曼樹:是一顆最優二叉樹。給定n個權值做爲n個葉子的結點,構造一棵二叉樹,若樹的帶權路徑長度達到最小,這棵樹則被稱爲哈夫曼樹。
所以本題根據哈夫曼算法,咱們以最小比較次數爲例:
首先從隊列中選出兩個最小的數進行合併,並在隊列中刪除這兩個數,並將新合成數加入隊列中。
再取最小的兩個數再進行合併,以此類推,獲得最終的大數以下
所以最小比較次數爲:( 7 - 1 ) + ( 18 - 1 ) + ( 30 - 1 ) = 52,即爲所得。最大比較次數也是同理。
AC代碼以下:
#include<bits/stdc++.h> using namespace std; priority_queue<int> Haff; priority_queue<int, vector<int>, greater<int> > Haff2; int n,ans1,ans2; int main() { cin>>n; for(int i = 0;i<n;i++) { int temp; cin>>temp; Haff.push(temp); Haff2.push(temp); } while(1) { if(Haff.size() == 1) break; int temp1 = Haff.top(); Haff.pop(); int temp2 = Haff.top(); Haff.pop(); Haff.push(temp1+temp2); ans1 += temp1+temp2-1; } while(1) { if(Haff2.size() == 1) break; int temp1 = Haff2.top(); Haff2.pop(); int temp2 = Haff2.top(); Haff2.pop(); Haff2.push(temp1+temp2); ans2 += temp1+temp2-1; } cout<<ans1<<" "<<ans2; return 0; }
由分析易知,雖然進行了兩次優先隊列維護,可是總的時間複雜度數量級是不變的,用O(n/2)的時間pop和push合成樹。在優先隊列裏面用紅黑樹對順序進行維護,時間複雜度爲O(nlogn),最後將統計的結果輸出,總的時間複雜度爲O(nlogn)。
空間複雜度爲兩棵紅黑樹,即T(2n) = O(n)。
通過動態規劃的肆虐以後,貪心算法變得稍微容易不少,和三木小哥哥的合做很愉快,可以很好較快及時的解決三道實踐問題,暫無太多的問題,繼續加油。
若有錯誤不當之處,煩請指正。