zoukankan      html  css  js  c++  java
  • 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.

    Input

    The first line contains one integer t (1t100)t (1≤t≤100) : the number of queries.

    Each query contains two lines. The first line contains one integer n (1n100000)n (1≤n≤100000) : the number of models in the shop, and the second line contains nn integers s1,,sn (1si109)s1,…,sn (1≤si≤109) : the sizes of models.

    It is guaranteed that the total sum of nn is at most 100000100000 .

    Output

    Print tt lines, the ii -th of them should contain the maximum number of models that Orac can buy for the ii -th query.

    Example
    Input
    Copy
    4
    4
    5 3 4 6
    7
    1 4 2 3 6 4 9
    5
    5 4 3 2 1
    1
    9
    
    Output
    Copy
    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;
    }
    
    
    





  • 相关阅读:
    磁盘缓存
    算法与追MM(转)
    人人都能上清华(转)
    软件加密技术和注册机制原理攻略(转)
    计算二重定积分
    C++运算符重载
    STL中list的用法
    累了??放松一下,看几张关于程序员的几张搞笑图片
    解决来QQ消息后歌曲音量降低问题
    搞ACM的你伤不起(转)
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/12880726.html
Copyright © 2011-2022 走看看