贪心法删数问题
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,删数过程如下
‘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>
相关文章推荐
- 贪心法解决连续背包问题
- 用贪心法解决图的着色问题
- 贪心法 南阳oj 背包问题
- 贪心法求解背包问题(物品可分)
- 一般背包问题 贪心法
- 事件序列问题 贪心法
- 贪心法 区间选点问题 南阳oj 找点
- 贪心法——活动选择问题和背包问题
- java背包问题(贪心法)
- 用贪心法找零问题
- 贪心法 活动选择问题
- 贪心法 背包问题求解
- C++作业: 贪心法求解问题
- 多机调度问题(贪心法)
- 贪心法解一个数组交集问题
- 背包问题-贪心法-java实现
- 用贪心法求解背包问题
- 动态规划法和贪心法解决0/1背包问题的差别(1)
- 经典贪心法:时间序列问题及其全局最优性证明
- 【算法学习笔记】51. 贪心法 区间排序问题 SJTU OJ 1360 偶像丁姐的烦恼