『嗨威說』算法設計與分析 - PTA 程序存儲問題 / 刪數問題 / 最優合併問題(第四章上機實踐報告)

本文索引目錄:

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、實驗心得體會(實踐收穫及疑惑)

 

 

1、PTA實驗報告題1 : 程序存儲問題

  1.1  實踐題目:

 

  1.2  問題描述:

      題意是,題幹給定磁盤總容量和各個文件的佔用空間,詢問該磁盤最多能裝幾個文件。

 

  1.3  算法描述:

      簽到題,只須要將各個文件從小到大排序,並拿一個變量存儲已佔用的容量總和,進行對比便可獲得結果。

#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;
 } 

 

  1.4  算法時間及空間複雜度分析:

     總體算法上看,輸入須要O(n)的時間進行輸入,最快用O(nlogn)的時間複雜度進行排序,使用O(n)的時間進行結果疊加,總時間複雜度爲O(nlogn),時間複雜度花費在排序上。

    空間上,只須要一個臨時變量存儲當前佔用容量總和便可。

 

 

2、PTA實驗報告題2 : 刪數問題

  2.1  實踐題目:

 

  2.2  問題描述:

    第二題題意是指,在給定的數字串以及可刪數個數的條件下,刪數指定k個數,獲得的數是最小的。

 

  2.3  算法描述:

    首先,分析題目,刪數問題,能夠用一個比較方便的函數,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;
}

 

  2.4  算法時間及空間複雜度分析:

    時間複雜度爲O(n^2),即開銷在不斷的刪數和回溯到字符串頭的過程。

    空間複雜度須要一個String字符串長度,所以空間複雜度是O(n)

 

 

3、PTA實驗報告題3 : 最優合併問題

  3.1  實踐題目:

 

  3.2  問題描述:

    該題目爲:題目用 2 路合併算法將這k 個序列合併成一個序列,而且合併 2 個長度分別爲m和n的序列須要m+n-1 次比較,輸出某段合併的最大比較次數和最小比較次數。

 

  3.3  算法描述:

    這道題算是哈夫曼算法的一道裸題,很容易解決,只須要使用優秀隊列不斷維護最小值或最大值便可。

    哈夫曼樹:是一顆最優二叉樹。給定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;
 } 

 

  3.4  算法時間及空間複雜度分析:

    由分析易知,雖然進行了兩次優先隊列維護,可是總的時間複雜度數量級是不變的,用O(n/2)的時間pop和push合成樹。在優先隊列裏面用紅黑樹對順序進行維護,時間複雜度爲O(nlogn),最後將統計的結果輸出,總的時間複雜度爲O(nlogn)。

   空間複雜度爲兩棵紅黑樹,即T(2n) = O(n)。

 

 

4、實驗心得體會(實踐收穫及疑惑):

    通過動態規劃的肆虐以後,貪心算法變得稍微容易不少,和三木小哥哥的合做很愉快,可以很好較快及時的解決三道實踐問題,暫無太多的問題,繼續加油。

 

 

若有錯誤不當之處,煩請指正。

相關文章
相關標籤/搜索