1、实践题目
删数问题
2、问题描述
给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。
3、算法描述(说明你的贪心策略,并且参考会场安排问题,利用反证法证明贪心选择和最优子结构性质)
定义一个数组来装要删的数字,从0~n比较数字大小,当前一个数字比后一个数字大的时候也就是出现降序排列的时候,用循环把较大的数删去,依此直到删完所需要删的数为止,如此最后得到的数就是最小的。代码如下:
#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
char a[300];
int k;
while(scanf("%s",a)!=EOF)
{
if(strcmp(a,"0")==0)
break;
scanf("%d",&k);
int l=strlen(a),t=k;
while(k)
{
int j=strlen(a)-1,flag;
for(int i=0;i<l-1;i++)
{
if(a[i]>a[i+1])
{
flag=1;j=i;break;
}
}
if(flag==1)
{
for(int i=j;i<l-1;i++)
a[i]=a[i+1];
}
k--;
}
for(int i=0;i<l-t;i++)
cout<<a[i];
cout<<endl;
}
return 0;
}
4、算法时间及空间复杂度分析(要有分析过程)
空间复杂度:只调用了一个数组记录数字,因此空间复杂度为O(n);
时间复杂度:程序中有两段while循环,每段循环为O(n),因此时间复杂度为O(n^2)
5、心得体会(对本次实践收获及疑惑进行总结)
刚开始拿到题目时第一反应是直接一个个比较过去,把最大的删掉之后剩下的数当然是最小的,但实际打出来却不行,经过老师举出反例改变想法才最终做出来,从这次实践我感受到贪心算法并不像看上去那么简单,实际很多细节方面的东西没有考虑到结果会差很多,而事实也确实是能想到的选择方案很多时候会存在反例,若是不仔细考究就自以为是正确的话,会卡住无法往前。
浙公网安备 33010602011771号