1. 程式人生 > >演算法:(貪心演算法)--刪數問題

演算法:(貪心演算法)--刪數問題

刪數問題(需知道的數學定理)

給定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;
}