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\n",ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值