您的位置:首页 > 其它

贪心法删数问题

2014-09-16 19:49 253 查看


【题目】

过键盘输入一个高精度的正整数n(n的有效位数≤240),去掉其中任意s个数字后,剩下的数字按

原左右次序将组成一个新的正整数。编程对给定的n 和s,寻找一种方案,使得剩下的数字组成的新数最小。

输入:n

s

输出:最后剩下的最小数

【样例输入】

178543

S=4

【样例输出】

13

【分析】

由于正整数n的有效位数最大可达240位,所以可以采用字符串类型(最大256)来存储n。那么,应如何来确定

该删除哪s位呢?

贪心法简介

贪心选择策略:可以通过做局部最优(贪心)选择来达到全局最优解。

贪心策略通常是自上而下进行的,第一步为一个贪心选择,将原问题编程一个相似的,但规模更小的问题,而后每一步都是当前看似最佳的选择,这种选择可以依赖已作出的所有选择,但不依赖于有待于做的选择或子问题的解。

解题思路

以字符串形式输入N,设N有P位,则第一步选择一个使剩下的P-1位数最小的字符删除,把问题归纳为在P-1位正整数里面去掉S-1个正整数后的新数最小的问题,依次类推。

为了保证删除一个字符后的数最小,按高位到低位的方向搜索递减区间,若不存在递减区间则删除尾数符;否则删除递减区间的首字符,形成一个新的数串,然后回到串首,以此类推,直至删除S个数符为止。

例如:N='178543',S=4,删数过程如下


N=


‘1 7 8 5 4 3’


‘1 7 5 4 3’


’1 5 4 3‘


‘1 4 3’
‘1 3’

代码如下所示(VS2010调试通过):


<span style="font-size:18px;">#include<iostream>
#include<string>
using namespace std;
int main()
{
string N;
int s;
cin>>N;
cin>>s;
int m=N.size();
if(s>=m)
{
N.erase();
return 0;
}
while(s>0){
int i;
for(i=0;(i<N.size()-1) && (N[i]<=N[i+1]);i++)
;
N.erase(i,1);
s--;
}
while(N.size()>1 && N[0]=='0')
N.erase(0,1);
cout<<N<<endl;
system("pause");
return 0;
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心法 删数问题