codeforces1061c

Posted pandaking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces1061c相关的知识,希望对你有一定的参考价值。

题意:给你一个序列a1,a2,a3,.....,an。如果其中取出一个子序列满足b1,b2,.....,bn.满足如下关系,如果对任意bi都满足bi%i==0.那么称这个序列为好好好序列,求这个序列中有多少个好好好序列。

         (这道题我一开始是往区间dp和最长公共子序列那儿去想的,但是接下来就卡在了转移上面,然后还有就是数组开不下)

         (然后接下来的话,我觉得这样不行,又把重心放到那儿以i结尾上升序列长度为j的数列上面了,这是我就比较接近正解了,然后预处理我也大概想好了,但是接下来不知道怎么把时间复杂度和空间复杂度降下来)

          (然后接下来就有点自闭了,就一直卡住卡住,没有啥思路)

其实你的第一维是可以去掉的,这样可以起到降低空间复杂度的作用。然后往后面走的话,对当前这个长度j影响是(以前的长度j的值)加上(以前长度j-1的值),然后每次取以当前点结尾的值

下面是代码:

           

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <vector>
 7 using namespace std;
 8 typedef long long ll;
 9 const ll mod=1e9+7;   
10 const int maxn=1000100; 
11 int n;
12 vector<int> mt[maxn];//用vector啊。。。。。。。。。。
13 //为什么我一直想到是哈希,哈希。。。。。。。
14 ll dp[maxn];
15 ll ans=0;
16 int main(){
17     scanf("%d",&n);
18     for(int i=1;i<=n;i++){
19         int x;
20         scanf("%d",&x);
21         for(int j=1;j*j<=x;j++){
22             if(x%j==0){
23                 mt[i].push_back(j); 
24                 if(j*j!=x) mt[i].push_back(x/j);
25             }
26         }
27         sort(mt[i].begin(),mt[i].end());
28     }
29     dp[0]=1;
30     for(int i=1;i<=n;i++){//从1到n
31         for(int j=mt[i].size()-1;j>=0;j--){ //一点要从后到前,这样来判断。
32             dp[mt[i][j]]=(dp[mt[i][j]]+dp[mt[i][j]-1])%mod;//这个是分两种情况,一是已经达到了j个,就是不要当前这位,二是还没有到达j,要当前这样
33             ans=(ans+dp[mt[i][j]-1])%mod;//以当前这位截止的长度为j的。。。。这样可以减少重复
34         }
35     }
36     printf("%lld
",ans);
37     return 0;
38 }
View Code

 



以上是关于codeforces1061c的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1061C (DP+滚动数组)

cf1061c 普通dp题

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

c_cpp Codeforces片段

Codeforces 86C Genetic engineering(AC自动机+DP)

CodeForces 1005D Polycarp and Div 3(思维贪心dp)