算法第四章实验报告

1.算法分析

1.1 问题描述

题目:删数问题

给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。如果数字最前面有0不输出。

输入格式:第 1 行是1 个正整数 a。第 2 行是正整数k。

输出格式:输出最小数。

1.2算法描述

贪心选择性质

题目要求设计一个算法,找出剩下数字组成的新数最小的删数方案。

ps:如果数字最前面有0不输出;数字顺序不变。

因此,我没可以将问题进行拆分,每一次删数后新产生的数字均是最小数。

贪心策略:从最左边(a[0])开始遍历,将前后两个数字进行比较,当前面的数字大于后面的数字的时候,删掉前面的数字a[i],并将删除数字右边的数字全部向左移一位( a[i] = a[i + 1] )。

补充:跳过首字0

1     int i = 0;
2     while(i < len && a[i] == '0')  //判断数字是否以0开头 
3     {
4         i++;  //跳过0,然后再开始输出 
5     }

2.代码

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;    
 5 
 6 int main()
 7 {
 8     string a; 
 9     int n;
10     cin >> a;
11     cin >> n;
12     
13     int len;
14     len = a.size();  //求数组长度 
15     
16     int j = 0;
17     for(int k = 0; k < n; k++)  //循环条件:删除n个数 
18     {
19         for(int i = 0; i < len - 1; i++)
20         {
21             if(a[i] > a[i+1])  //如果前面的数大于后面的数,应该将前面的数删除 
22             {
23                 for(int t = i; t < len - 1; t++ )
24                 {
25                     a[t] = a[t+1];
26                 }
27                 break;  //退出当前循环,开始寻找下一个删除的数 
28             }
29         }
30         len--;
31     }
32     
33     int i = 0;
34     while(i < len && a[i] == '0')  //判断数字是否以0开头 
35     {
36         i++;  //跳过0,然后再开始输出 
37     }
38     
39     if(i == len)  //全部数字都是0 
40     {
41         cout << "0";
42     }
43     else
44     {
45         for(int j = i; j < len; j++)  //跳过0再开始输出 
46         {
47             cout << a[j]; 
48         }
49     }
50 }

3.时间复杂度分析

时间复杂度:O(nk) ----n指删除的数字个数,k指的是数组长度。

解释:每删除一个数字,都需要遍历整个数组找到需要删除的数,即为删除个数*数组长度

4.对贪心算法的理解

贪心算法的主要步骤:

  • 建立模型描述问题

  • 将求解问题分解为若干子问题

  • 找到子问题的局部最优解(运用贪心思想,找到合适的贪心策略)

  • 将局部最优解合并为最终答案

贪心算法的缺陷:

  • 不能保证求得最优解

  • 不能求最值问题

  • 只能求满足某些约束条件的可行解的范围(求解问题必须有限定范围)

posted @ 2021-11-16 19:17  Shannonn  阅读(46)  评论(0编辑  收藏  举报