434
社区成员
发帖
与我相关
我的任务
分享1. 请用反证法证明“删数问题”的算法满足贪心选择性质(即设最优解不包含贪心选择,则可以通过转换找出一个更小的数,推出矛盾)
删数的代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
string a;
cin >> a;
int k;
int len = a.length();
cin >> k;
while(k > 0){
int flag = 0;
for(int i = 0; i < len - 1; i++){
if(a[i] > a[i+1]){
for(int j = i; j < len - 1; j++){
a[j] = a[j+1];
}
len--;
k--;
flag = 1;
break;
}
}
if(flag == 0){
len -= k;
k = 0;
}
}
if(len == 0){
cout << 0;
return 0;
}
int i = 0;
while(a[i] == '0' && i < len){
i++;
}
for(; i < len; i++){
cout << a[i];
}
}
采用的贪心策略是:从数组的第一位开始找到第一段递减区间,删去递减取区间的第一个数字。
例如:3215689740
假设我们删去一个数,我们选择的是删去之后高位最小的数,即215689740;
删去两个数,15689740;
删去三个数,15689740:1689740,1589740,1569740,1568740,1568940,1568970,1568974,可得最终的数字为1568740
如果我们采用贪心选择时所得到的最终结果不是最小的值,说明我们在删去第一个数或者第二个数的时候有更优的选择,但是我们在采用贪心选择时所得到的已经是最优的选择了,所以不存在有更优的最终解。
2. 结合本章的学习,总结你对贪心法的体会和思考
贪心法是在每一步都对当前的处境做出一个最优的选择,没有动态规划的回退等操作,每一步操作就是一个当前最优的选择。核心思路是基于一步步的局部最优解希望能够导出全局最优解。
这可能导致它找到的只是满足需求的最优解,而不是全局的一个最优解。
还有一个就是不能解决具有后效性的问题。对于这类问题,贪心算法无能为力,因为它无法回退到之前的状态重新做出决策。