传送门

https://www.cnblogs.com/violet-acmer/p/10005351.html

 

题意:

  给定一数组a[],从a[ ]中除去任意个元素得到b[ ],求能形成多少“好序列”;

  好序列的定义是:对于任意的 i 有 b[i]%i == 0(1 ≤ i ≤ size_b[ ])。

题解:

  相关变量解释:

1 int n;
2 int a[maxn];
3 int dp[maxn];//dp[i] : 下标i处可以获得的最大的"好序列"
4 int factor[maxn];//factor[i] : 记录a[i]的因子

  步骤:

   (1):从a[1]开始遍历整个数组;

   (2):来到a[i]处,将a[i]因式分解,找到其所有的因子factor,并判断其是否在[1,i ]范围内,如果在dp[factor] += dp[factor-1];(对于所有的factor)

具体看代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 const int MOD=1e9+7;
 9 const int maxn=1e5+10;
10 
11 int n;
12 int a[maxn];
13 int dp[maxn];//dp[i] : 下标i处可以获得的最大的"好序列"
14 int factor[maxn];//factor[i] : 记录a[i]的因子
15 
16 void updataDp(int i)
17 {
18     int index=1;
19     for(int j=1;j*j <= a[i];++j)
20     {
21         if(a[i]%j == 0)//判断j是否为a[i]的因子
22         {
23             factor[index++]=j;//记录a[i]的因子
24             if(a[i]/j != j && a[i]/j <= i)//判断其另一个因子a[i]/j是否 <= i,并判断其是否等于 j
25                 factor[index++]=a[i]/j;
26         }
27     }
28     sort(factor+1,factor+index);
29     for(int j=index-1;j >= 1;--j)//从大因子到小因子,防止a[i]的小因子影响大因子
30     {
31         int x=factor[j];
32         dp[x] += dp[x-1];
33         dp[x] %= MOD;
34     }
35 }
36 int Solve()
37 {
38     mem(dp,0);
39     dp[0]=1;
40     for(int i=1;i <= n;++i)//遍历a[]
41         updataDp(i);//由a[i]更新dp[]
42 
43     int res=0;
44     for(int i=1;i <= n;++i)
45         res=res%MOD+dp[i];
46 
47     return res%MOD;
48 }
49 int main()
50 {
51     scanf("%d",&n);
52     for(int i=1;i <= n;++i)
53         scanf("%d",a+i);
54     printf("%d\n",Solve());
55 }
View Code

相关文章:

  • 2021-11-01
  • 2022-12-23
  • 2021-08-21
  • 2022-01-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-05-20
  • 2021-06-28
  • 2021-09-30
  • 2022-02-08
  • 2021-09-06
  • 2022-12-23
相关资源
相似解决方案