1. 程式人生 > >51nod 1255 貪心/構造

51nod 1255 貪心/構造

時間限制 bit == 構造 bool pid 技術 小寫 href

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1255

1255 字典序最小的子序列技術分享

題目來源: 天津大學OJ 基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題 技術分享 收藏 技術分享 關註 給出一個由a-z組成的字符串S,求他的一個子序列,滿足如下條件:
1、包含字符串中所有出現過的字符各1個。 2、是所有滿足條件1的串中,字典序最小的。 例如:babbdcc,出現過的字符為:abcd,而包含abcd的所有子序列中,字典序最小的為abdc。 Input
輸入1行字符串S,所有字符均為小寫,字符串的長度為L。(1 <= L <= 100000)。
Output
輸出包含S中所有出現過的字符,每個字符各1個,並且字典序最小的S的子序列。
Input示例
babbdcc
Output示例
abdc

一開始只考慮了待替換字符後面相鄰的那一個字符沒想到還有可能出現後面數個在後面都可以被更換使得字典序更小的情況,改了以後還是WA竟然是因為前綴和數組zz的寫錯了cao。。。
假設字符x已經出現過了,現在考慮將x刪掉查到後面會不會使得結果更優,那麽x後面肯定要出現一個小於x的字符且這二者間的字符再後面都要能替換,否則的話並不能使答案優化。
 1 #include<bits/stdc++.h>
 2 using namespace std;
3 char s[100005]; 4 deque<char>q; 5 bool vis[26]; 6 int num[26]; 7 int main() 8 { 9 scanf("%s",s+1); 10 int len=strlen(s+1),n,m,i,j,k; 11 for(i=1;i<=len;++i) num[s[i]-a]++; 12 for(i=1;i<=len;++i) 13 { 14 if(!vis[s[i]-a]){ 15 vis[s[i]-a]=1;
16 q.push_back(s[i]); 17 } 18 else{ 19 for(j=0;j<q.size();++j) 20 { 21 if(q[j]==s[i]){int j1=-1; 22 { 23 for(k=j+1;k<q.size();++k){ 24 if(q[k]<q[j]){j1=k;break;} 25 } 26 if(j1!=-1){ 27 bool ok=1; 28 for(k=j+1;k<j1;++k) 29 { 30 if(num[q[k]-a]<=0){ok=0;break;} 31 } 32 if(ok){ 33 q.erase(q.begin()+j); 34 q.push_back(s[i]); 35 } 36 } 37 } 38 break; 39 } 40 } 41 } 42 num[s[i]-a]--; 43 } 44 for(int i=0;i<q.size();++i)cout<<q[i];puts(""); 45 return 0; 46 }

51nod 1255 貪心/構造