0
点赞
收藏
分享

微信扫一扫

洛谷P2193 HXY和序列【DP】【黄】

Ichjns 2022-03-17 阅读 31

Date:2022.03.17
题目描述
HXY突发奇想,她想要找到一个正整数序列,满足序列中所有的数不超过n,序列长度为p,且除了第一个数外,所有的数都能被前一个数整除(即是前一个数的倍数)。很快她找到了一个这样的序列。可是她觉得还不够,想要知道这样的序列有多少个,可她被惊人的数据范围吓怕了。现在她找到了你,请你来帮助她解决这个问题。(因为结果可能会很大,请输出对1e9+7取模后的值)
输入格式
第一行,两个正整数n,p。
输出格式
仅一行,一个正整数,表示满足条件序列的个数对1e9+7取模后的值。
输入输出样例
输入 #1复制
3 2
输出 #1复制
5
输入 #2复制
6 4
输出 #2复制
39
说明/提示
数据范围:
对于10%的数据,p=1;
对于30%的数据,1<=n,p<=10;
对于60%的数据,1<=n,p<=500;
对于100%的数据,1<=n,p<=2000。

思路: f [ i ] [ j ] : f[i][j]: f[i][j]:以第 i i i个字符结尾,长度为 j j j串的合法方案数。
状态转移方程: f [ i ] [ j ] + = f [ k ] [ j − 1 ] ; 【 其 中 i % k = = 0 】 f[i][j]+=f[k][j-1];【其中i\%k==0】 f[i][j]+=f[k][j1];i%k==0
初始状态: f [ i ] [ 1 ] = 1 ; f[i][1]=1; f[i][1]=1;【即只有它自己一个数】
由于三维,打表出所有 k k k,即使2000的约数也只有20个,所以k很小不必担心。
答案可以是以每个元素结尾的,累加下。
代码如下:

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
const LL N = 2020,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
typedef pair<LL, LL> PII;
LL t,n,m,k,f[N][N],sum[N];
vector<LL>v[N];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=0;i<=n;i++) f[i][1]=1;
    for(int i=1;i<N;i++)
    {
        for(int j=1;j<=i;j++)
            if(i%j==0) v[i].push_back(j);
    }
    for(int i=1;i<=n;i++)
        for(int j=2;j<=m;j++)
            for(int k=0;k<v[i].size();k++)
                    f[i][j]=(f[i][j]+f[v[i][k]][j-1])%mod;
    LL sum=0;
    for(int i=1;i<=n;i++) sum=(sum+f[i][m])%mod;
    cout<<sum;
    return 0;
}
举报

相关推荐

0 条评论