牛客IOI周赛23-普及组 D.小L的数列 (dp状态+枚举因子)

简介: 牛客IOI周赛23-普及组 D.小L的数列 (dp状态+枚举因子)

原题链接

思路:

看到这题第一眼觉得要用些数论的知识优化,决定先写个暴力。

假设dp[i]表示枚举到第i项的时候最长的好的序列长度,转移仿照LIS的n^2转移,过了80。

然后就不会优化了。

宇巨说可以枚举因子进行优化:

///dp[i]表示以数i为结尾的最长的好的序列长度
///dp1[i]表示因数包括i的数结尾的最长好的序列长度

这样转移的时候将第二层for改成sqrt(n)的复杂度,并且在过程中用dp1更新dp,枚举完因子后,再用此数的dp更新因子的dp1。

ps:

1.要对原数组进行排序,因为第一个要求

2.注意因子为1时不进行转移

事实证明,dp的状态选择多么重要(逃

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a,ll b,ll p)
{
    ll res=1;
    while(b)
    {
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
#define PI acos(-1)
#define x first
#define y second
const int maxn=1e6+7,inf=0x3f3f3f3f;
int n,a[maxn],dp[maxn],dp1[maxn],w[maxn];
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int t=read;
    while(t--){
        n=read;
        rep(i,1,n) a[i]=read;
        sort(a+1,a+1+n);
///dp[i]表示以数i为结尾的最长的好的序列长度
///dp1[i]表示因数包括i的数结尾的最长好的序列长度
        memset(dp,0,sizeof dp);
        memset(dp1,0,sizeof dp1);
        int res=1;
        for(int i=1;i<=n;i++){
            dp[a[i]]=1;
            int idx=0;
            if(a[i]==1) continue;
            for(int j=1;j*j<=a[i];j++){
                if(a[i]%j==0){
                    int x1=a[i]/j,x2=j;
                    if(x1==x2){
                        if(x1!=1) dp[a[i]]=max(dp[a[i]],dp1[x1]+1),w[++idx]=x1;
                    }
                    else{
                        if(x1!=1) dp[a[i]]=max(dp[a[i]],dp1[x1]+1),w[++idx]=x1;
                        if(x2!=1) dp[a[i]]=max(dp[a[i]],dp1[x2]+1),w[++idx]=x2;
                    }
                }
            }
            for(int j=1;j<=idx;j++) dp1[w[j]]=max(dp1[w[j]],dp[a[i]]);///枚举a[i]的因子
        }
        for(int i=1;i<=n;i++) res=max(res,dp[a[i]]);
        printf("%d\n",res);
    }
    return 0;
}
目录
相关文章
|
7月前
|
算法 测试技术
枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)
枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)
|
5月前
【洛谷】P1308 [NOIP2011 普及组] 统计单词数
然后要被查找的b字符串,可能会出现第二个样例中的情况,也就是字符串a是to,而字符串b的Ottoman,这样是不符合题意的。为了 解决这个问题,我们将字符串a首尾都加一个空格,同时将字符串b首尾都加一个空格(这里是为了让字符串b的首单词和尾单词前后均有空格)为了能持续找字符串b中的所有字符串a,我们用一个while循环,如果能找到,就每次从能找到的位置的下一个位置(也就是能找到的位置下标+1)开始找,并及时更新位置,同时计数。因为不区分大小写,所以可以将两个字符串a,b都转为小写(也可以都转为大写)。
151 10
【洛谷】P1308 [NOIP2011 普及组] 统计单词数
|
6月前
【洛谷 P1036】[NOIP2002 普及组] 选数 题解(深度优先搜索+判断质数+枚举子集)
**NOIP2002普及组选数问题**:给定$n$个整数和一个整数$k$,需找出所有$k$个数的组合,计算它们的和为素数的种类数。输入包含$n$和$k$,以及$n$个整数;输出是符合条件的组合数。例如,对于输入`4 3`和数组`[3, 7, 12, 19]`,输出为`1`。代码使用递归枚举子集并检查质数的方法。
97 0
|
6月前
|
机器学习/深度学习 人工智能
【洛谷 P1028】[NOIP2001 普及组] 数的计算 题解(递推)
在NOIP2001普及组的数的计算题目中,给定自然数`n`,需构造遵循特定规则的合法数列。合法序列始于`n`,新元素不超过前一项的一半。任务是找出所有这样的数列数量。例如,当`n=6`时,合法序列包括`6`, `6,1`, `6,2`, `6,3`, `6,2,1`, `6,3,1`。程序通过动态规划求解,当`i`为奇数时,`a[i] = a[i - 1]`;为偶数时,`a[i] = a[i - 1] + a[i / 2]`。代码中预处理数组`a`并输出`a[n]`作为答案。输入`n`后,程序直接计算并打印合法数列个数。
77 0
|
6月前
|
存储
【洛谷 P2141】[NOIP2014 普及组] 珠心算测验 题解(集合+多重循环)
**NOIP2014普及组的珠心算测验题要求参赛者找出给定集合中多少个数可表示为其他两个不同数的和。输入含n个正整数,输出满足条件的数的个数。样例输入4个数,输出2,因1+2=3且1+3=4。代码利用集合存储和,遍历所有数对组合,当找到匹配和时插入集合,最后输出集合大小。注意数据规模为n≤100,数不超过10,000。**
141 0
|
6月前
|
机器学习/深度学习 存储
【洛谷 P1028】[NOIP2001 普及组] 数的计算 题解(递归)
**NOIP2001普及组数的计算**:给定自然数\( n \),构造数列,新数不超过序列最后一项一半。求合法数列个数。输入\( n \)(\(1 \leq n \leq 10^3\))。样例:输入6,输出6。递归解决,代码中定义函数`f`实现递归计算,总和存储在`cnt`中,最后输出。
59 0
|
6月前
【洛谷 P1035】[NOIP2002 普及组] 级数求和 题解(循环)
**NOIP2002普及组题目:求级数$S_n=1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}$超过$k$的最小$n$。给定$1\leq k\leq 15$,输出满足$S_n&gt;k$的$n$。输入$1$个整数$k$,输出相应$n$。例如,输入$1$,输出$2$。代码中使用double确保精度,通过累加求和判断条件找到$n$。**
46 0
|
7月前
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
【错题集-编程题】删除相邻数字的最大分数(动态规划 - 线性 dp)
|
7月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-201 大等于n的最小完全平方数
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-201 大等于n的最小完全平方数
34 0
|
7月前
|
人工智能
力扣每日一题 -- 2919. 使数组变美的最小增量运算数
力扣每日一题 -- 2919. 使数组变美的最小增量运算数