删除算法

问题描述:

通过键盘输入一个高精度的正整数n(n的有效位数≤240),去掉其中任意s个数字后,
剩下的数字按原左右次序将组成一个新的正整数。编程对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小。


问题分析:

这个问题是最优子结构问题,即局部最优能决定全局最优解,可以使用贪心算法进行解决
。n个正整数去掉s个数字,求使得到的新的正整数最大的删除方案可以等价为:对于n个正整数组成的数字,一个一个地依次去掉s个数字
,要求每删除一个数时,都使删除后的新的正整数最小。因此问题转化为求解删除一个数字时是新的数字最小的方案,求得这个方案后只需要对其执行s次即可。

因为删数后剩下的数字原左右次序不变,所以要尽可能在左边删除,我们从左往右进行考虑,
假设n个整数为a(1),a(2)....a(n),当由左往右第一次出现a(k)>a(k+1),可以发现,①删除任何一个a(k)之前的元素得到的新数都比删除a(k)得到的新数大
,所以可以明确a(k)之前的元素可以排除;②倘若删除a(k),则新的数字第k位变成a(k+1),记这个新的数字为c,倘若删除a(k)之后的任何一位,
得到的新的数字第k位仍然是a(k),记这个新的数字为d。比较c和d,可以发现,c(1)=d(1),......,c(k-1)=d(k-1),因为a(k)>a(k+1),所以c(k)<d(k),
那么有c<d。综上可知,对于数字a,应该删除由左往右第一次出现a(k)>a(k+1)时的a(k),如果a的数字序列一直是非减的,那么删除最后一位即可

复制代码
#include<bits/stdc++.h>
using namespace std;

static int flag=0;
static int flag2=0;
int main(void)
{
int n ;
int s;
string st;
string st1;

cin>> st >> s;
st1=st;
for(int i=0;i<s;i++){
for (int m=0;m<st1.length();m++){
if(st1[m]>st1[m+1]){
flag=m;
break;
}

}
flag2=st1.length();
string sa="";
for (int m=0;m<flag2;m++){
if(m!=flag){
sa.append(1,st1[m]);
}
}
st1=sa;

}
cout <<st1 <<endl;
return 0;
}
复制代码

 

posted @   你的雷哥  阅读(906)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示