演算法:(貪心演算法)--刪數問題
阿新 • • 發佈:2019-02-02
刪數問題(需知道的數學定理)
給定n位正整數a,去掉其中任意k≤n 個數字後,剩下的數字按原次序排列組成一個新 的正整數。對於給定的n位正整數a和正整數 k,設計一個演算法找出剩下數字組成的新數最 小的刪數方案。
定理: ex:1 2 3 9 5;刪掉一個數;
從第一個數開始遍歷,到尋找到單調遞減的第一個數(即單調遞增的最後一個數),則刪除,若無單調遞減子序列,則刪掉最後一個非遞減序列的數;每找到一個就又從頭開始。即每做一次刪數,就是一次貪心選擇,刪掉此數剩下的數為組成最小,經過證明,此結論正確。
ex:1 2 3 9 5,刪掉三個數;
1:1 2 3 5
2:1 2 3
3:1 2
注意一種情況:3 0 0 2,刪去一個數;
應該是2,而不是002
Input
第 1 行是1 個正整數 a。第 2 行是正整數k。 |
Output
輸出最小數 |
Sample Input
178543 4 |
Sample Output
13 |
#include<iostream>; #include<cstring>; using namespace std; int shanshu(char *a,int k) { int n = strlen(a); while (k > 0) {//每次刪一個數,使得剩下的數按原序列組成最小。 for (int i = 0; i < n; i++) { if (i == n - 1) { n--; break; }//沒找到那個單調遞減的第一個數,就刪掉非遞減序列的最後一個數。 else if (a[i] > a[i + 1]) { for (int j = i; j < n - 1; j++) { a[j] = a[j + 1];//刪掉一個,後面的全部前移一位。 } n--;//長度減一 break; } } k--; } return n; } int main() { char* input = new char();//char型別陣列 cin >> input; //cout << input[1];是一個數組。 //cout << strlen(input);可以這樣獲得長度:strlen int k; cin >> k; int m = shanshu(input, k); int b = 0; while((b<(m-1))&&(input[b]=='0'))b++; //注意是char,所以不能是0,一定是'0'。 //處理上述注意的情況,即002這種情況 for (int i = b; i < m; i++) { cout << input[i]; } system("pause"); return 0; }