天天看點

問題 E: 最長上升字串

問題 E: 最長上升字串

時間限制: 3 Sec  記憶體限制: 128 MB

題目描述

給定n個整數,對其進行m次查詢。每次查詢是一個範圍l到r,求出l到r的最長上升連續子串。上升連續子串的定義為一個連續的子串且嚴格遞增。

輸入

第一行是一個整數T,代表測試資料的組數。每組資料中第一行是一個整數n,m,代表有一共有n個人,m個查詢。第二行共有n個整數,接下來m行是m次查詢,每行兩個整數l,r。

輸出

共T行,每行m個整數,代表最長上升連續字串。其中T<=50,m<1e5,每個數的大小不超過1e9。

樣例輸入

1
4 2
3 2 4 5
1 3
1 4
           

樣例輸出

2 3
           

解法一: 直接搜尋,但這題還是用動态規劃做比較好接受,解法二在下面

#include<cstdio>
#include<algorithm>
using namespace std;

int arr[10000];
int t,n,m,l,r,ans;

void solve(int now,int index,int lenth)
{
    if(now==r)
    {
        ans=max(ans,lenth+1);
        return;
    }
    if(arr[index]>arr[now]) 
		solve(index,index+1,lenth+1);
    else solve(now,index+1,lenth);
}

int main(){
    
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        scanf("%d%d",&n,&m);
        for(int j=1;j<=n;j++) scanf("%d",&arr[j]);
        for(int k=0;k<m;k++) 
        {
            scanf("%d%d",&l,&r);
            ans=0;
            for(int p=l;p<r;p++)
            {
            	solve(p,p+1,0);
	    }
            printf("%d ",ans);
        }
    }
	return 0;
}
           

解法二: 動态規劃

#include<cstdio>
#include<algorithm>
using namespace std;

int arr[10000],dp[10000];
int t,n,m,l,r,ans;

int main(){
    
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        scanf("%d%d",&n,&m);
        for(int j=1;j<=n;j++) scanf("%d",&arr[j]);
        for(int k=0;k<m;k++) 
        {
            scanf("%d%d",&l,&r);
            ans=0;
            for(int p=l;p<=r;p++)
			{
				dp[p]=1;
				for(int q=l;q<p;q++)
				{
					if(arr[q]<arr[p]&&p-q==1) dp[p]=max(dp[p],dp[q]+1);
				}
				ans=max(ans,dp[p]);
			} 
            printf("%d ",ans);
        }
    }
	return 0;
}
           

繼續閱讀