牛客题库 21738 牛牛与数组

牛牛与数组题目链接
题目大意
牛牛喜欢这样的数组:

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

请问一共有多少满足条件的数组,对 1 e 9 + 7 1e^9+7 1e9+7 取模
输入格式
输入两个整数 n , k n,k n,k
1 ≤ n ≤ 10 , 1 ≤ k ≤ 100000 1 ≤ n ≤ 10,1 ≤ k ≤ 100000 1n101k100000
输出格式
输出一个整数
输入样例

3 3

输出样例

15

1.确定状态 f [ i ] [ j ] : f[i][j]: f[i][j]: 表示长度为 i i i j j j 结尾的满足题意得方案数。
2.状态转移: f [ i ] [ j ] f[i][j] f[i][j] = f [ i − 1 ] [ a ] + f [ i − 1 ] [ b ] f[i-1][a] +f[i-1][b] f[i1][a]+f[i1][b] 1 ≤ a ≤ t , t + 1 ≤ b ≤ k 1\leq a \leq t , t + 1 \leq b \leq k 1at,t+1bk
优化就是求一下前缀和后缀,然后减去不满题意得部分,即减去 b > a b > a b>a a n d and and b % a = 0 b\%a =0 b%a=0
最后答案就是求累计求和。 f [ n ] [ 1... k ] f[n][1...k] f[n][1...k]
样例满足方案的所有组合

1 1 1

1 2 2
1 3 2
1 1 2
2 2 2
2 3 2 
3 2 2
3 3 2

1 3 3
1 1 3
1 2 3
2 3 3
2 2 3
3 2 3
3 3 3 
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 7, mod = 1e9 + 7;
int f[11][maxn];
int pre[maxn], stu[maxn];
int main()
{
    
    
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i = 1; i <= k; i++) f[1][i] = 1;
    
    for(int i = 2; i <= n; i++)
    {
    
    
        memset(pre, 0, sizeof pre);
        memset(stu, 0, sizeof stu);
        for(int j = 1; j <= k; j++) pre[j] = (pre[j-1] + f[i-1][j])%mod;
        for(int j = k; j >= 1; j--) stu[j] = (stu[j+1] + f[i-1][j])%mod;
        for(int j = 1; j <= k; j++)
        {
    
    
            f[i][j] = (pre[j] + stu[j])%mod;
            for(int s = j; s <= k; s += j)
                f[i][j] = (f[i][j] + mod - f[i-1][s])%mod;
        }
    }
    int ans = 0;
    for(int i = 1; i <= k; i++) ans = (ans + f[n][i])%mod;
    printf("%d\n",ans%mod);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Edviv/article/details/111032702
今日推荐