1. 程式人生 > >最長不降子序列(二)

最長不降子序列(二)

受到(一)中啟發,現補充位元組跳動19年第二次筆試第四題程式。

其中第一部分轉載:空氣質量題,作者:whl_program

題目如下:

4.一天,小凱同學震驚的發現,自己屋內的PM2.5指標是有規律的!小凱取樣了PM2.5的數值,發現PM2.5數值以小時為週期迴圈,即任意時刻的PM2.5總是和一小時前相等!他的室友小文同學提出了這樣一個問題,在t小時內的所有采樣點中,選取若干取樣點的數值,能否找到一個PM2.5不曾下降過的序列?這個序列最長是多少?

輸入描述:

第一行有兩個整數n t 表示每小時的取樣點個數,和詢問多少個小時的結果

第二行有n個整數,以空格分隔,表示一個小時內,每個取樣點觀測到的PM2.5的數值

示例:

輸入

4   3

10   3   7  5

輸出

4

說明

3小時內所有采樣點為

10  3  7  5  10  3  7  5  10  3  7  5

選取第2 3 5 9個取樣點,可以得到一個不曾下降過的序列

3  7  10  10

使用其他的方法也可以得到長為4的滿足條件的序列,但無法得到長度超過4的結果

1、採用容器類的方式編寫程式碼,參考以上提到的作者的博文,程式碼如下:

int main()
{
	int a,b;
	scanf("%d%d", &a, &b);
	vector<int> ans(a, 0),tmp(a,1);
	for (int i = 0;i<a;i++)
	{
		scanf("%d", &ans[i]);
	}
	for (int i = 1;i<a;i++)
	{
		for (int j = 0;j<i;j++)
		{
			if (ans[i]>=ans[j])
			{
				tmp[i] = max(tmp[i], tmp[j] + 1);
			}
		}
	}
	cout << *max_element(tmp.begin(), tmp.end())+b-1;
return 0;
}

2、第二部分-參考(一)種思路,採用陣列的形式編寫

int main
{	
        int a[40005];
	int d[40005];
	int n,t;
	scanf("%d",&n);
	scanf("%d",&t);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	if (n==0)  //0個元素特判一下 
	{
		printf("0\n");
		return 0;
	}
	d[1]=a[1];  //初始化 
	int len=1;
	for (int i=2;i<=n;i++)
	{
		if (a[i]>=d[len]) d[++len]=a[i];  //如果可以接在len後面就接上 
		else  //否則就找一個最該替換的替換掉 
		{
			int j=upper_bound(d+1,d+len+1,a[i])-d;  //找到第一個大於它的d的下標 
			d[j]=a[i]; 
		}
	}
	printf("%d\n",len+t-1);  
return 0;
}