問題描述 :
給定n位正整數a,去掉其中任意k≤n 個數字后,剩下的數字按原次序排列組成一個新 的正整數。對於給定的n位正整數a和正整數 k,設計一個算法找出剩下數字組成的新數最 小的刪數方案。
輸入格式:
第 1 行是1 個正整數 a。第 2 行是正整數k。
輸出格式:
輸出最小數。
輸入樣例:
178543 4
輸出樣例:
13
代碼實現
#include <iostream> using namespace std; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char** argv) { string a; int k; cin>>a>>k; int len=a.size(); while(k--) for(int i=0;i<len;i++) if(a[i]>a[i+1]||i==len-1) { a.erase(i,1); //抹去數組下標為i的一個數 break; } while(a[0]=='0'&&a[1]>0) //當前面的數是0時或者防止數全部為0是數組為null的情況 a.erase(0,1); cout<<a<<endl; return 0; }
算法描述:
我們的貪心策略是使得剩下的數盡量的小,因此我們要保留的數字應該是前面一位數應該比后面的數小,然后根據貪心算法步驟逐步進行。
-
把求解的問題分成若干個子問題;
-
對每一子問題求解,得到子問題的局部最優解;
-
把子問題的解局部最優解合成原來解問題的一個解。
把問題分成求解前一個數和后一個數的大小問題,每一步都要求是最小的值,然后去掉大的那個值,當剩下的數是升序時,我們應該從最后的數開始刪(因為最后那個數最大)。
算法時空分析:
從代碼可以看到時間復雜度為兩個循環的時間最多即O(n2),空間復雜度為數組的長度即O(n)。
小結:
發現很多庫函數自己還不熟悉,下次做題時應該多了解一些庫函數,以減少代碼量。