码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces1061c

时间:2018-12-01 23:44:18      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:include   color   style   max   src   --   using   pen   namespace   

题意:给你一个序列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\n",ans);
37     return 0;
38 }
View Code

 



codeforces1061c

标签:include   color   style   max   src   --   using   pen   namespace   

原文地址:https://www.cnblogs.com/pandaking/p/10051277.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!