Codeforces Round #641 (Div. 2) B. Orac and Models(线性DP)
There are nn models in the shop numbered from 11 to nn , with sizes s1,s2,…,sns1,s2,…,sn .
Orac will buy some of the models and will arrange them in the order of increasing numbers (i.e. indices, but not sizes).
Orac thinks that the obtained arrangement is beatiful, if for any two adjacent models with indices ijij and ij+1ij+1 (note that ij<ij+1ij<ij+1 , because Orac arranged them properly), ij+1ij+1 is divisible by ijij and sij<sij+1sij<sij+1 .
For example, for 66 models with sizes {3,6,7,7,7,7}{3,6,7,7,7,7} , he can buy models with indices 11 , 22 , and 66 , and the obtained arrangement will be beautiful. Also, note that the arrangement with exactly one model is also considered beautiful.
Orac wants to know the maximum number of models that he can buy, and he may ask you these queries many times.
The first line contains one integer t (1≤t≤100)t (1≤t≤100) : the number of queries.
Each query contains two lines. The first line contains one integer n (1≤n≤100000)n (1≤n≤100000) : the number of models in the shop, and the second line contains nn integers s1,…,sn (1≤si≤109)s1,…,sn (1≤si≤109) : the sizes of models.
It is guaranteed that the total sum of nn is at most 100000100000 .
Print tt lines, the ii -th of them should contain the maximum number of models that Orac can buy for the ii -th query.
4 4 5 3 4 6 7 1 4 2 3 6 4 9 5 5 4 3 2 1 1 9
2 3 1 1
第二题竟然是个DP,惊到我了
大意是给n个数,求出最长递增子序列的大小,这个子序列每相邻两个数里前一个数的下标能整除后一个数的下标。
正着其实不好分析,不如倒着来看。首先定义DP数组:DP[i]为以a[i]为当前数的最长递增子序列的长度。
容易看出数组要初始化为1。然后可以知道,当i大于n/2时,这时i后面已经没有i的倍数了,所以从i=n/2遍历到1,这是外层的“阶段”;
内层的转移过程为遍历i的倍数,转移方程为dp[i]=max(dp[i],dp[j]+1)(i|j)
#include <bits/stdc++.h> using namespace std; int n,a[100005],dp[100005]; int main() { int t; cin>>t; while(t--) { memset(dp,0,sizeof(dp)); cin>>n; int i,j,ans=1; for(i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i]=1; } for(i=n/2;i>=1;i--) { for(j=i;j<=n;j+=i) { if(a[j]>a[i]) { dp[i]=max(dp[i],dp[j]+1); ans=max(ans,dp[i]); } } } cout<<ans<<endl; } return 0; }