原題鏈接
題目大意:
就是給你一個長度爲n的序列,讓你從中找出一個滿足以下條件的子序列,(序列要遞增,並且找到的子序列中元素下標在原序列中後者下標可以整除前者)
思路:
看到三秒的時限可以想到暴力,但實現難度過大,舉個例子,首先選擇下標爲1的元素,那麼爲了整除下一個元素可以選2,選3,同理,選了2下一個可以選4,選6,依次類推,所以想到dp,那麼接下來設計狀態,設dp[i]表示從i到n這個序列中最長的滿足條件的子序列,那麼dp[i]=max(dp[j]+1)
要保證j能夠整除i,所以j每次加i。最後在1到n中選擇最大的dp[i]即可。
代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
const int maxn=1e6;
int s[N],dp[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s[i];
dp[i]=1;
}
for(int i=n;i>=1;i--)
{
for(int j=i+i;j<=n;j+=i)
{
if(s[i]<s[j]&&dp[i]<dp[j]+1)
dp[i]=dp[j]+1;
}
}
int ans=0;
for(int i=1;i<=n;i++)
ans=max(dp[i],ans);
cout<<ans<<endl;
}
return 0;
}