算法第四章上机实验报告
实践题目
4-2 删数问题 (30 分)
给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。如果数字最前面有0不输出。
在这里给出一组输入。例如:
178543 4 结尾无空行
5001 1 结尾无空行
在这里给出相应的输出。例如:
13 结尾无空行
1 结尾无空行
解题代码如下:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main(){
char a[101];
int k;
cin >> a >> k;
int len, i;
while(k>0){
i = 0;
len = strlen(a);
while(i<len&&a[i]<=a[i+1])
i++;
while(i<len){
a[i] = a[i+1];
i++;
}
k--;
}
i=0;
len = strlen(a);
while(a[i]=='0'&&i<len)
i++;
if(i==len)
cout << '0';
else{
for(i=i;i<len;i++)
cout << a[i];
}
return 0;
}
贪心算法策略
该题目用的贪心算法是,要让高位尽量小(因为要剩下数字组成的新数最小),那么就是,在一串数字中从左到右找到递增序列的最后一位(如果没有,就找递减序列的第一位),然后删掉这一位。需要执行这个过程k次,然后如果有前导0则删除前导0,然后输出。
算法时间复杂度和空间复杂度:
时间复杂度
O(nk),双重while()循环,最外层需要循环k次,删除k位数,内层需要循坏n次,删除了一个数之后将删除的数后面那些数往前移一位。
空间复杂度
O(1)没有用到特别的额外空间,只用到了一些普通变量。
对贪心算法的理解
我对贪心算法的理解就是,不看整体最优,看的是局部最优。每走一步只看当下,做一个当下最佳的决定。当然,用贪心算法之前一定要想好用何种贪心算法,要学会举反例筛选贪心算法,因为有一些算法看似贪心,其实并不能得到最优解(有反例)。同时,要注意能用贪心算法的问题要满足两个性质:贪心选择性质和最优子结构性质。
心得体会
用贪心算法解题能大大提高效率,但是在写代码之前我们一定要想好贪心策略,再写代码,这样才不会出错。