算法第4章实验报告

算法第4章实践报告

 

  • 1. 实践题目名称

  • 1.1 问题描述

  这道题的意思是:在给定的数字串以及可删数个数的条件下,删数指定k个数,得到的数是最小的。

  • 1.2 算法描述

  为了让删数后的数最小,高位应该尽可能的小,所以在使用贪心算法策略的时候应该从最高位作比较删除

  确定我们的贪心策略:当当前的数,比后一位数大时,删去当前的数

  删去数的时候,需要多一个下标变量 j 去代表遍历的 i 变量去删数。

  这道题有个坑点,那就是前导零,需要注意100000,删除1后结果应为0

 

代码实现

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int main(){
 7     int n, i, j, k;
 8     string a;
 9     
10     cin>>a>>n;
11     int len=a.size();
12      
13     //删数过程(删掉k个数) 
14     for(k=0; k<n; k++){
15         for(i=0; i<len-1; i++){
16             //从最高位开始比较,若a[i] > a[i+1](高位比地位的数字更大),该位后面所有位往前挪一位(删掉a[i])
17             if(a[i] > a[i+1]){
//用变量j遍历后面变量,让后一个变量代替前一个,实现删数的目的
18 for(j=i; j<len-1; j++) 19 a[j] = a[j+1]; 20 break; 21 } 22 } 23 //删掉一位后len-- 24 len--; 25 } 26 27 i = 0; 28 //删数最后的数以0开头的情况 29 while(i <= len-1 && a[i] == '0')i++; 30 31 //若全为0的情况 32 if(i == len) 33 cout<<"0"<<endl; 34 //从第一个非0开始输出 35 else 36 for(j=i; j<=len-1; j++) 37 cout<<a[j]; 38 39 return 0; 40 }

 

  • 1.3 算法时间复杂度分析

   删数过程中,k次循环删数中嵌套两个与输入字符串长度n相关的循环,则时间复杂度为:O(k*n*n)

   删数完成之后,一次检查0的循环:O(n)

   则最后的时间复杂度为:O(n²)

  • 2. 贪心算法的个人理解和体会

  贪心算法主要思路是:
  (1)把求解的问题分成若干个子问题;
  (2)对每个子问题求解,得到子问题的局部最优解;
  (3)把子问题的局部最优解合成原来问题的一个解。

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅仅是在某种意义上的局部最优解

就是说,贪心算法所得出的解,不一定是全局最优解。初看不理解,为什么得不到全局最优解呢?看过别人写的文章才知道,这跟子问题最优解的选择有关。贪心算法其实是动态规划(DP)的一种特殊情况,它的关键词是“局部最优”,每次只做当前对于自己最“有利”的选择,而动态规划则是要寻找“全局最优”,并且一定能找到“全局最优解”。

简言之,贪心算法比较符合人的思维,即每次都选择最有利于自己的选项,不考虑其他方面,也不考虑未来会怎样。

posted @ 2021-11-12 13:36  满鸡  阅读(74)  评论(0编辑  收藏  举报