牛牛与数组(DP)

链接:https://ac.nowcoder.com/acm/problem/21738
来源:牛客网
 

题目描述

牛牛喜欢这样的数组:
1:长度为n
2:每一个数都在1到k之间
3:对于任意连续的两个数A,B,A<=B 与(A % B != 0) 两个条件至少成立一个

请问一共有多少满足条件的数组,对1e9+7取模

输入描述:

输入两个整数n,k

1 ≤ n ≤ 10
1 ≤ k ≤ 100000

输出描述:

输出一个整数
输入
2 2
输出
3

输入
9 1
输出
1

输入
3 3
输出
15

输入
2 1234
输出
1515011

思路:不能根据所影响这一步的加和来解决这个问题,会时间超限。 DP[i][j]代表数组长度为i时以j结尾的有多少种方法(1<=j<=k),当j=0时是数组长度为i时总的方法数,对于需要满足的条件A<=B || A % B != 0成立的太多了,我们可以找他的对立面A>B&&A%B==0,然后用总方法数减去不满足条件的就是该位置的结果。

AC代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int mod=1e9+7;
const int M=1e5 + 10;
ll dp[11][100100];
int main()
{
    int n,k,kk;
    cin >> n >> k;
    memset(dp, 0, sizeof(dp));
    dp[1][0]=k;
    for(int i=1;i<=k;i++){
        dp[1][i]=1;
    }
    for (int i = 2; i <= n;i++){
        for(int j=1;j<=k;j++){
            dp[i][0]+=dp[i][j];
            dp[i][0]%=mod;
        }
        for(int j=1;j<=k;j++){
            int sum=0;
            for(int kk=j*2;kk<=k;kk+=j){
                sum+=dp[i-1][kk];
                sum%=mod;
            }
            dp[i][j]=(dp[i-1][0]-sum)%mod;
            dp[i][0]=(dp[i][0]+dp[i][j])%mod;
        }
    }
    cout << dp[n][0]%mod << endl;
    return 0;
}

 

你可能感兴趣的:(dp)