貪心算法實驗總結


貪心算法實驗總結

一、題目1描述

4-1 程序存儲問題 (40 分)

設有n 個程序{1,2,…, n }要存放在長度為L的磁帶上。程序i存放在磁帶上的長度是 li,1≤i≤n。 程序存儲問題要求確定這n 個程序在磁帶上的一個存儲方案, 使得能夠在磁帶上存儲盡可能多的程序。 對於給定的n個程序存放在磁帶上的長度,計算磁帶上最多可以存儲的程序數。

 

輸入格式:

第一行是2 個正整數,分別表示文件個數n和磁帶的長度L。接下來的1行中,有n個正整數,表示程序存放在磁帶上的長度。

 

輸出格式:

輸出最多可以存儲的程序數。

 

輸入樣例:

在這里給出一組輸入。例如:

 

6 50

2 3 13 8 80 20

結尾無空行

輸出樣例:

在這里給出相應的輸出。例如:

 

5

結尾無空行

 

二、貪心策略:最小程序優先存入磁盤

 

三、具體實現:把所有的程序按長度有小到大排序,在將程序放入磁盤前先判斷程序和磁盤的長度大小來判斷程序能否放入程序,若能放入,磁盤存儲長度減去放進的程序的長度,計數變量加一,最后輸出計數變量

 

四、代碼實現:

#include <iostream>

#include <algorithm>

using namespace std;

int n,L;

int a[1000];

 

 

int main(int argc, char** argv) {

   cin>>n>>L;

   for(int i=1;i<=n;i++){

      cin>>a[i];

   }

   sort(a,a+n);

   int count =0;

 

   for(int i=1;i<=n;i++){

      if(a[i]<=L){

          count++;

            L -= a[i];

      }

   }

   cout<<count;

   return 0;

}

 

一、題目2描述

   4-2 刪數問題 (30 分)

給定n位正整數a,去掉其中任意k≤n 個數字后,剩下的數字按原次序排列組成一個新的正整數。對於給定的n位正整數a和正整數 k,設計一個算法找出剩下數字組成的新數最小的刪數方案。如果數字最前面有0不輸出。

 

輸入格式:

第 1 行是1 個正整數 a。第 2 行是正整數k。

 

輸出格式:

輸出最小數。

 

輸入樣例:

在這里給出一組輸入。例如:

 

178543

4

結尾無空行

5001

1

結尾無空行

123456

2

結尾無空行

109

1

結尾無

二、貪心策略:把數字以字符形式輸入,再轉換成數字比較,從左邊開始比較,若左邊的數字比右邊的大,則刪除該數,若該數為最后一位,則刪除該數本身,若比較完之后,還沒有刪除要求的個數,而此時數組已經按遞增排列,所以從最后一位開始刪掉剩余的個數即可。

三、代碼實現:

import java.util.Scanner;

 

public class Main {

 

    private static String a;

    private static int k;

    private static int m;

    private static StringBuffer str;

 

    public static void main(String[] args){

        Scanner input = new Scanner(System.in);

 

        while (true){

            a = input.next();

            k = input.nextInt();

 

            m = a.length();

            str = new StringBuffer(a);

 

            delk();

 

            System.out.println(str);

        }

    }

 

    //最近下降點優先

    private static void delk(){

        int i;

        if(k >= m)

            return;

        while (k > 0){

            for(i=0; (i<str.length()-1) && (str.charAt(i)<=str.charAt(i+1)); i++);//注意這里是提取str中的遞增元素,將大的數字跳出循環然后刪除

            str.deleteCharAt(i);

            k--;

        }

        while(str.length()>1 && str.charAt(0)=='0')

            str.deleteCharAt(0);

    }

}

 

一、題目3描述

   PTA 程序設計類實驗輔助教學平台

算法第4章實踐

剩余時間:1天

4-3 最優合並問題 (30 分)

題目來源:王曉東《算法設計與分析》

 

給定k 個排好序的序列, 用 2 路合並算法將這k 個序列合並成一個序列。 假設所采用的 2 路合並算法合並 2 個長度分別為m和n的序列需要m+n-1 次比較。試設 計一個算法確定合並這個序列的最優合並順序,使所需的總比較次數最少。 為了進行比較,還需要確定合並這個序列的最差合並順序,使所需的總比較次數最多。

 

輸入格式:

第一行有 1 個正整數k,表示有 k個待合並序列。 第二行有 k個正整數,表示 k個待合並序列的長度。

 

輸出格式:

輸出最多比較次數和最少比較次數。

 

輸入樣例:

在這里給出一組輸入。例如:

 

4

5 12 11 2

結尾無空行

輸出樣例:

在這里給出相應的輸出。例如:

 

78 52

結尾無空行

 

二、貪心策略

       最少比較次數:最短序列優先比較,將待合並序列按從短到長排列,每次從中選取最短的兩個序列計算比較次數,每次比較之后,要把被比較元素的下一個元素加上其前面的元素,並且要重新對待排序序列進行排序,因為元素經過改變后可能會使得原來的序列的遞增規律被破壞

  最多比較次數:與最少相反,最長優先,其余類比最少比較次數

 

三、代碼實現

      #include <iostream>

#include <algorithm>

using namespace std;

int n;

int a[1000];

int b[1000];

 

 

bool comp(int a ,int b){

      return a>b;

}

 

int main(int argc, char** argv) {

      cin>>n;

      for(int i=1;i<=n;i++){

              cin>>a[i];

              b[i]=a[i];

      }

     

      int max=0;

      int min=0;

      for(int i=1;i<n;i++){

              sort(a+i,a+n+1);

              min+=a[i]+a[i+1]-1;

              a[i+1]+=a[i];

      }

      for(int i=1;i<n;i++){

              sort(b+i,b+n+1,comp);

              max+=b[i]+b[i+1]-1;

              b[i+1]+=b[i];

      }

      cout<<max<<" "<<min;

      return 0;

}

 

實驗心得:對於貪心算法相關問題首先需要找出解決問題的貪心策略,然后再具體實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM