題目:html
鍵盤輸入一個高精度的正整數N(不超過250位) ,去掉其中任意k個數字後剩下的數字按原左右次序將組成一個新的正整數。ios
編程對給定的N和k,尋找一種方案使得剩下的數字組成的新數最小。算法
算法思路:編程
要從正整數中刪除k個數字,能夠採起一步步來刪的策略,每一次刪除一個數字,使得當前獲得的數字是最小的,執行k步後,即獲得最後的結果。函數
經過子問題的最優解來獲得整個問題的最優解,就是貪心的思想。spa
例如:7122145這個數字,若是k=3,第一次刪除的應該是7,獲得122145;第二次刪除的應該是5,獲得12214;第三次刪除的應該是4,獲得1221.code
經過觀察,能夠發現每次刪除的數字有這樣的規律:htm
都是整個數字中遞減區間的第一個數字,若是整個數中沒有遞減區間,就刪除最後一個數字,由於要想留下的數字最小,它的高位確定要儘量小,blog
這樣刪除的方法,在當前次看來都是最優的,咱們把降序區間的第一個數刪掉,就能夠讓後面比他小的數前進一個高位,那麼數字也就變小了,ci
若是咱們刪除了這個最優數字前面的數,那麼這個比較大的數字就前進了一個高位,反而讓數字變大了,
一樣的,若是咱們刪除這個數後面的也很大的數字,雖然能讓小的數也前進一個高位,可是它自己處的位置也很低,顯然沒有讓利益最大化。
上代碼:
1 #include<iostream>
2 #include<string>
3 using namespace std; 4 int main() { 5 string n; 6 int k; 7 cin >> n; 8 cin >> k; 9 while (k != 0) { 10 int flag = 0; 11 for (int i = 0; i < n.length()-1; i++) { 12 if (n[i] > n[i + 1]) { 13 n.erase(i, 1); 14 flag = 1; 15 break; 16 } 17 } 18 //若是數字都是單調遞增的,就刪除最後一個
19 if(!flag) n.erase(n.length() - 1, 1); 20 k--; 21 } 22 int i = 0; 23 if (n == "0") { 24 cout << n; 25 return 0; 26 } 27 //將首位的0去掉
28 while (n[i] == '0') { 29 i++; 30 } 31 for (int j = i; j < n.length(); j++) { 32 cout << n[j]; 33 } 34
35 return 0; 36 }
其中,string中的erase()函數的用法在個人另外一篇博客中有總結。