[算法]在数字N中删除S个数,使其最终余下的值最小

本文介绍了一种针对高精度正整数的算法,该算法通过移除指定数量的数字来构造一个尽可能小的新整数。通过逐步迭代删除当前数字串中左侧的最大数字,最终得到目标最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

输入一个高精度的正整数N(N不超过200位),去掉其中任意S个数字后剩下的数字按原左右次序组成一个新的正整数:编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数字最小

private string Calc(string N, int S)
{
if (S <= 0) return N;
char c = N[0];
int j = 0;
for (int i = 1; i < N.Length - 1; i++)
if (c > N[i])
return Calc(N.Remove(j, 1), S - 1);
else if (c < N[i])
{
c = N[i];
j = i;
}
return N;
}

/*---演算过程
N=234[9]0293847213847958723489502319482035345983958727351925,S=20
N=23[4]0293847213847958723489502319482035345983958727351925,S=19
N=2[3]0293847213847958723489502319482035345983958727351925,S=18
N=[2]0293847213847958723489502319482035345983958727351925,S=17
N=02[9]3847213847958723489502319482035345983958727351925,S=16
N=023[8]47213847958723489502319482035345983958727351925,S=15
N=0234[7]213847958723489502319482035345983958727351925,S=14
N=023[4]213847958723489502319482035345983958727351925,S=13
N=02[3]213847958723489502319482035345983958727351925,S=12
N=0[2]213847958723489502319482035345983958727351925,S=11
N=0[2]13847958723489502319482035345983958727351925,S=10
N=013[8]47958723489502319482035345983958727351925,S=9
N=01347[9]58723489502319482035345983958727351925,S=8
N=0134[7]58723489502319482035345983958727351925,S=7
N=01345[8]723489502319482035345983958727351925,S=6
N=01345[7]23489502319482035345983958727351925,S=5
N=0134[5]23489502319482035345983958727351925,S=4
N=013[4]23489502319482035345983958727351925,S=3
N=01[3]23489502319482035345983958727351925,S=2
N=012348[9]502319482035345983958727351925,S=1
*/

对于删除数字问题,第一次删除一个数字所得到的最大整数是当前的最优解,然后剩下的整数继续删除一个数字,得到的最大整数仍然是当前的最优解,以此类推,每次删除数字都选择得到当前最优解的策略。因此,最终删除k个数字后余下的最大整数即为整体的最优解。根据贪心算法的基本步骤,求解思路如下: 设大整数组为a[0,1,..,n−1],每个数组元素表示大整数的一,大整数的最高为a[0],最低为a[n−1],用赋为−1来表示删除操作,例如a[1]=−1,则表示删除组索引1处的数字; 求解n个纯数字组成的数字删除k个数字后余下最大整数的问题,可以划分为k个子问题:删除1数字余下最大整数问题。 依次对每个子问题求解:从左往右查询(i=0→n−2),对于组a中出现的第一个据对a[i]<a[i+1],删除a[i]后余下整数一定比删除a[i+1]后余下整数要大(其余数字置不变,相连两个数字中,删除小的数字a[i]后余下整数a[0,1,..i−1,i+1,i+2,..n−1]一定比删除大的数字a[i+1]余下整数a[0,1,..,i−1,i,i+2,..n−1]要大,因为新的整数在第i个置上的数字前者大于后者)。为了实现方便,而不需要组移来形成新的整数,按先前的设定,将a[i]赋为−1,往后的子问题在求解时注意跳过为−1的数字。 k个子问题依次求解出最优解之后,得到的整数即为n个数字串删除k个数字后余下的最大整数。 上面第3步在求解k个子问题时用的是暴力尝试的方法,复杂度为O(k∗n),为了提高算法执行效率,可以维护每个子问题求解后i的置,而不是每次都从头开始,这样子的算法复杂度为O(n+k),具体维护方法是:当a[i]=−1时,让i往左移(i=i−1),直到i=0或a[i]!=−1为止。
最新发布
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值