算法第四章作业
1.对贪心算法的理解:
贪心法是求解一类最优化问题的方法,它总是考虑在当前状态下局部最优(或较优)的策略,来使全局的结果达到最优(或较优)。显然,如果采取较优而非最优的策略(最优策略可能不存在或者不易想到),得到的全局结果也无法是最优的。而要获得最优的结果,则要求中间的每一步策略都是最优的,因此严谨使用贪心法来求解最优化问题需要对采取的策略进行证明。证明的一般思路是使用反证法及数学归纳法,即假设策略不能导致全局最优解,然后通过一系列推导来得到矛盾,以此证明策略是最优的,最后用数学归纳法保证全局最优。不过对平常使用来说,也许没有时间或不太容易对想到的策略进行严谨的证明(贪心法的证明往往比贪心法本身更难),因此一般来说,如果在想到某个似乎可行的策略,并且自己无法举出反例,那么就勇敢的实现它。
2.满足贪心选择的性质:
4-2 删数问题 (110分)
给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。
输入格式:
第 1 行是1 个正整数 a。第 2 行是正整数k。
输出格式:
输出最小数。
输入样例:
在这里给出一组输入。例如:
178543
4
输出样例:
在这里给出相应的输出。例如:
13
贪心策略:
显然高位数位对数值大小起到决定性的作用,因此从高位开始贪心,保留小数字。每一位删除的都是最靠近左也就是靠近高位的极值,若没有极值,则删除末尾元素可保证得到最小数字。
#include<iostream> #include<string> using namespace std; int main(){ string a; int k; cin>>a>>k; while(k>0){ int i=0; for(;(i<a.size()-1)&&(a[i]<=a[i+1]);++i); a.erase(i,1); k--; } while(a.size()>1&&a[0]=='0'){ a.erase(0,1); } cout<<a<<endl; }
3.本章学习过程中遇到的问题及结对编程的情况
贪心算法整体上没有动态规划(需求解状态转移方程及边界)难,但其证明比贪心本身难,所以结对编程时都是想到一个似乎可行的策略直接干,但结果要么是运气好过了,要么是需要重新选择另一个策略。