1. 程式人生 > >最多01子序列問題

最多01子序列問題

01子序列問題

 問題描述
給定 n 個二進位制字串,要求調整字串順序並連線所有的字串,使最後得到的字串中有儘可能多的“01”子序列。輸出“01”子序列的最大個數。 (1 ≤ n ≤ 100000)。
 解題思路與演算法思想

我們先將字串分成四類
開頭是0結尾是1記為01
同理
四類字串
01
00
11
10
之後我們會發現只有10這種字串是可以連續連線的,因為可以保證最前面是0,
	我放上了10之後在前端形成了一個01字串並且在後面又出現了一個0
而01的字串對於形成多餘的另一序列沒有任何作用
00和11可以成對的拼接成為10字串
	剩下的邊角料也沒有什麼作用

 程式模型的建立

  • 選擇一個00作為開頭
  • 之後加上10和拼接而成的10
  • 最後以11結尾
  • 再加上邊角料

 資料結構的選用

  • vector
  • string

 程式設計流程

  • 儲存
  • 分類
  • 填充

 程式設計偽碼演算法

	while(a10.size()!=0)
	{
		sum.push_back(a10[a10.size()-1]) ;
		a10.pop_back() ;
	}
	//之後看0_1
	int c = min(a0.size(),a11.size()) ;
	for(int i = 0 ;i<c ;i++)
	{
		sum.push_back(a11[a11.size()-1]) ;
		a11.pop_back() ;
		sum.push_back(a0[a0.size()-1]) ;
		a0.pop_back() ;
	}
	c = min(a1.size(),a00.size()) ;
	for(int i = 0 ; i<c ;i++)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
		sum.push_back(a1[a1.size()-1]) ;
		a1.pop_back() ;
	}
	//合成00 11
	c = min(a00.size(),a11.size())  ;
	for(int i = 0 ;i<c ;i++)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
		sum.push_back(a11[a11.size()-1]) ;
		a11.pop_back() ;
	}

 源程式編碼清單

#include<iostream>
#include<vector>
#include<string>
#include<algorithm> 
using namespace std ;
int main(void)
{
	vector<string>sum ;
	vector<string>a00 ;
	vector<string>a11 ;
	vector<string>a01 ;
	vector<string>a10 ;
	vector<string>a0 ;
	vector<string>a1 ;
	int n ;
	scanf("%d",&n) ;
	
	for(int i = 0 ; i<n ;i++)
	{
		string tem ;
		cin>>tem ;
		if(tem.size()==1)
		{
			if(tem[0]== '0')
			{
				a0.push_back(tem) ;
				//cout<<"dsakd;salkdls;kdl;askdl;ksal;dka;s"<<endl;
			}
			if(tem[0] =='1')
			{
				a1.push_back(tem) ;
			}
		}
		else
		{
				//cout<<"int lese"<<endl ;
			//	cout<<"akjksa"<<*tem.begin()<<endl ;
			//	cout<<"askdjkks"<<tem[tem.size()-1]<<endl ;
			if((tem[0]=='0')&&(tem[tem.size()-1]=='1'))
			{
				a01.push_back(tem) ;
			}
			if((tem[0]=='1')&&(tem[tem.size()-1]=='1'))
			{
				a11.push_back(tem) ;
			}
			if((tem[0]=='0')&&(tem[tem.size()-1]=='0'))
			{
				a00.push_back(tem) ;
			}
			if((tem[0]=='1')&&(tem[tem.size()-1]=='0'))
			{
				a10.push_back(tem) ;
				//cout<<"here !"<<endl ;
			}
		}
	}
	//cout<<"sdkaldj"<<endl ;
	//先看開頭,如果都沒有那也沒有辦法 
	if(a00.size()!=0)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
	}
	else
	{
		if(a0.size()!=0)
		{
		sum.push_back(a0[a0.size()-1]) ;
		a0.pop_back() ;
		}
		
	}
	//內部
	//先將1——0放進去 
	while(a10.size()!=0)
	{
		sum.push_back(a10[a10.size()-1]) ;
		a10.pop_back() ;
	}
	//之後看0_1
	int c = min(a0.size(),a11.size()) ;
	for(int i = 0 ;i<c ;i++)
	{
		sum.push_back(a11[a11.size()-1]) ;
		a11.pop_back() ;
		sum.push_back(a0[a0.size()-1]) ;
		a0.pop_back() ;
	}
	c = min(a1.size(),a00.size()) ;
	for(int i = 0 ; i<c ;i++)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
		sum.push_back(a1[a1.size()-1]) ;
		a1.pop_back() ;
	}
	//合成00 11
	c = min(a00.size(),a11.size())  ;
	for(int i = 0 ;i<c ;i++)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
		sum.push_back(a11[a11.size()-1]) ;
		a11.pop_back() ;
	}
	//加上邊角料
	while(a0.size()!=0)
	{
		sum.push_back(a0[a0.size()-1]) ;
		a0.pop_back() ;
	}
	while(a1.size()!=0)
	{
		sum.push_back(a1[a1.size()-1]) ;
		a1.pop_back() ;
	}
		while(a11.size()!=0)
	{
		sum.push_back(a11[a11.size()-1]) ;
		a11.pop_back() ;
	}
		while(a10.size()!=0)
	{
		sum.push_back(a10[a10.size()-1]) ;
		a10.pop_back() ;
	}
		while(a01.size()!=0)
	{
		sum.push_back(a01[a01.size()-1]) ;
		a01.pop_back() ;
	}
		while(a00.size()!=0)
	{
		sum.push_back(a00[a00.size()-1]) ;
		a00.pop_back() ;
	}
	//	cout<<"sdkaldj"<<endl ;
	string sum1 ;
	string temc ;
	temc.push_back(0)  ;
	temc.push_back(1) ;
	int cnt = 0  ;
	//數出來個數
	//cout<<sum.size() ;
	for(int i = 0 ; i <sum.size() ;i++)
	{
		//cout<<sum[i]<<endl ;
	}
	for(int i = 0 ;i<sum.size() ;i++)
	{
		sum1+=sum[i] ;
	}
		cout<<sum1<<endl ;
	//	cout<<"sdkaldj"<<endl ;
	for(int i = 0 ;i<sum1.size() ;i++)
	{
		
			if(sum1[i]=='0'&&sum1[i+1]=='1')
			{
				cnt++ ;
			}
	}
	
	printf("%d\n",cnt) ; 
	
	
	
	
} 

 程式輸入、輸出

輸入:
3
00
11
01
輸出
001011
2

輸入輸出檔案或程式執行結果截圖
在這裡插入圖片描述

 時間與空間複雜度分析
空間複雜度:
n^2
 程式使用說明

 總結與完善