• T^T ONLINE JUDGE 1593 翻倍序列


    T^T ONLINE JUDGE 1593 翻倍序列


    翻倍序列
    TimeLimit:10000ms MemoryLimit:128000KB
    64-bit integer IO format:%lld
    已解决 | 点击收藏
    Problem Description
    满足序列中除了第一个数外每个数是它前一个数的倍数的序列被称为翻倍序列 现在要求满足如下条件的翻倍序列: 1.序列的所有元素是1~n的正整数 2.序列的长度是k 求满足这样的翻倍序列的数有几种。 由于答案能很大,输出答案MOD 1000000007(10^9+7)
    Input
    输入包括多组数据 每组数据是一行两个整数n,k。(1<=n,k<=2000)
    Output
    对于每个输入数据,输出一个整数表示答案
    SampleInput
    3 2
    6 4
    2 1
    SampleOutput
    5
    39
    2


    【思路】:

    这个题目有点毒,一开始我因为题意读错,做不出来,后来经过学长的解释题意,就懂了。翻倍序列指的是(x[i+1])/x[i]=k;k为一个常数。就对了。
    开一个dp【i】【j】的数组
    dp【i】【j】代表的是在i个长度下尾数为j的序列的数量
    我先将dp【1】【j】(1《=j《=n)全部=1,在进行下一步
    就是【i】【j】肯定由【i-1】【j】(1《=j《=n)转移过来,所以枚举状态就对了,但是这样的结果就是TLE ,那怎样才能ac呢?就是逆过来想下,
    【i】【j】的状态肯定由j%z==0的条件转移,那么我枚举z,令z一开始=j,(1《=j《=n)
    然后z+=j,更新每个值。这样的话,复杂度就由O(N3)->O(N2LOGN),就能AC了*

    附上代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN = 2005;
    const long long MOD = 1e9+7;
    int dp[MAXN][MAXN];
    
    int main()
    {
       // memset(dp,0,sizeof(dp));
        for(int i=1;i<=MAXN;i++)
            dp[1][i]=1;
        for(int i=2;i<=MAXN;i++)
        {
            for(int j=1;j<=MAXN;j++)
            {
                for(int z=j;z<=MAXN;z+=j)
                {
                    dp[i][z]=((dp[i][z]%MOD)+(dp[i-1][j]%MOD))%MOD;
                }
            }
        }
        int n,k;
        while(~scanf("%d%d",&n,&k))
        {int sum=0;
            for(int i=1;i<=n;i++)
                sum=((sum)%MOD+(dp[k][i])%MOD)%MOD;
            printf("%d
    ",sum);
        }
        return 0;
    }
    
  • 相关阅读:
    MySQL 之 Metadata Locking 研究
    Spring, MyBatis 多数据源的配置和管理
    ThreadLocal 源码剖析
    Java多线程中的死锁问题
    Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)
    PriorityQueue和Queue的一种变体的实现
    被我们忽略的HttpSession线程安全问题
    Java并发之原子变量和原子引用与volatile
    使用Java实现单线程模式
    这些年无处安放的博客
  • 原文地址:https://www.cnblogs.com/qq136155330/p/9102857.html
Copyright © 2020-2023  润新知