zoukankan      html  css  js  c++  java
  • ZOJ-Happy Sequence(记忆化(DP)搜索)

    这里写图片描述

    题意:找一种序列,使得 b【i+1】 % b【i】 =0,也就是说每一项都能被前一项整除,且b【i+1】>=b【i】。输入查找这样的序列的上限n,序列长度m,意思是在从1到n这段区间找长度为m的符合条件的序列种数。结果对1e9+7取模

    使用DFS记忆化搜索,直接暴力搜索肯定会超时。首先预处理打表出数据范围1~2000所有数的因子。倒着从n向前搜索序列。对于每次查找的的序列种数用DP数组记录,这样在一次搜索后可以多次使用。

    DP状态转移方程为:
    长度为len,搜索到 数字now 的序列 种数为 长度为len-1,搜索到 数字now的其中一个因子 的序列 种数 之和
    若数字now的其中一个因子的序列 种数 dp【len-1】【data【now】【i】】并未计算,则递归下去,计算该序列种数

    最终将序列终值由1到n的所有种数求和 ,得到长度为M 的序列所有种数

    #include<stdio.h>///递归记忆化(递归+DP)
    #include<string.h>
    #define MOD 1000000007
    #define ll long long
    int dp[2003][2003],data[2002][2002];
    int t,n,m;
    ll ans;
    void init()///1~2000所有数的因子
    {
        memset(data,0,sizeof(data));
        memset(dp,0,sizeof(dp));///DP数组在所有测试数据中都通用,因此每组数据都会相应增加DP出来的数据以供下次使用
        for(int i=1;i<=2000;i++)
        {
            int flag=0;
            for(int j=1;j<=i;j++)
                if(i%j==0) data[i][++flag]=j;
            data[i][0]=flag;///模拟链表,0位存有多少因子,然后依次是数字i的因子分别是谁
        }
    }
    ll dfs(int now,int len)///DFS搜索序列数量
    {
        if(now==1||len==1)return 1;///当当前搜索数为1时,不能再继续找1的因子,递归出口,搜索结束。或当搜索的序列长度到达上限时(剩余1),搜索结束。
        ll tmp=0;///临时存储到达数NOW时的序列数量。
        for(int i=1;i<=data[now][0];i++)///DP记录
        {
            if(dp[len-1][data[now][i]])tmp=((tmp%MOD)+(dp[len-1][data[now][i]]%MOD))%MOD;///若要计算长度为len,当前值为now的序列有多少种时,该结果由长度为len-1,当前值为now的一个因子的序列继承而来
            else tmp=((tmp%MOD)+(dfs(data[now][i],len-1)%MOD))%MOD;///若想要查找的序列还未计算有多少种,那么递归搜素这个序列的种数。
        }
        dp[len][now]=tmp;///最后将数字now的所有因子的种类求和之后,即是len长度,当前数now的 序列种数
        return tmp;
    }
    int main()
    {
        init();
        scanf("%d",&t);
        while(t--)
        {
            ans=0;///最终答案
            scanf("%d%d",&n,&m);
            for(int i=n;i>=1;i--) ans=((ans%MOD)+(dfs(i,m)%MOD))%MOD;///从最大的数n,最长的序列长度m开始查找这个序列。然后依次减小序列的终值来查找。
            printf("%lld
    ",ans);
        }
    }
    
  • 相关阅读:
    java几种常用设计模式简单示例
    字符串常用方法
    File类常用方法
    如何在一个form表单中实现多个submit
    CC EAL认证
    ARQC与ARPC的生成和校验方法
    金融卡IC卡知识50问
    M(必备),R(需求),C(条件),O(可选)
    非接触IC卡中typeA卡和typeB卡的区别--总结,二者的调制方式和编码方式不同
    电子钱包和电子存折的区别
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135856.html
Copyright © 2011-2022 走看看