• 动态规划-牛牛与数组


    题目描述 

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

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

    输入描述:

    输入两个整数n,k

    1 ≤ n ≤ 10
    1 ≤ k ≤ 100000

    输出描述:

    输出一个整数
    示例1

    输入

    复制
    2 2

    输出

    复制
    3
    示例2

    输入

    复制
    9 1

    输出

    复制
    1
    示例3

    输入

    复制
    3 3

    输出

    复制
    15
    示例4

    输入

    复制
    2 1234

    输出

    复制
    1515011
    思路:由于是两个条件至少成立一个。怕少算。所以转换成:没有条件的数组方案总和
    -A%B==0&&A!=B的数组方案总和。利用dp,从长度为1的数组往后推。
    其中dp[i][j]表示长度为i的数组第i位为j的符合要求的数组方案数
    #include <cstdio>
    #include <cstdlib>
    #include <climits>
    #include <fstream>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <iostream>
    using namespace std;
    
    typedef long long ll;
    const int mod = 1e9+7;
    const double PI=3.14159265358;
    const int INF=0x3f3f3f3f;
    
    ll dp[12][100010];
    //dp[i][j]表示长度为i的数组
    //第i位为j的符合要求的数组方案数。
    int main()
    {
    
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int n,k;
        cin>>n>>k;
        //初始化
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=k;i++)
        {
            //数组长度位1时,值为任何数的可能性都是1;
            dp[1][i]=1;
        }
        //sum记录所有的情况 dum记录A>B且A是B的倍数的情况
        ll sum=0,dum=0;
        //从第二层开始循环
        for(int i=2;i<=n;i++){
            sum=0;
    
            for(int j=1;j<=k;j++)
            {
                //累加,当i层值为j时
                //i-1层的值为1~k的可能性和。
                sum+=dp[i-1][j];
                sum%=mod;
            }
    
            for(int j=1;j<=k;j++)
            {
                //当第i层值为j时。
                dum=0;
                //假设第i层的值为B,i-1层的值为A
                //循环A=B的倍数的dp数组
                for(int l=j+j;l<=k;l+=j)
                {
                    dum=(dum+dp[i-1][l])%mod;
                }
                //当第i层值为j时,dp[i][j]的值
                //为i-1层所有的可能性的和减去不符合条件的和
                dp[i][j]+=(sum-dum)%mod;
            }
        }
        
        //循环,累加n层数组的值为1~k的可能性和
        ll ans=0;
        for(int i=1;i<=k;i++)
        {
            ans+=dp[n][i];
            ans%=mod;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Mac下各种编程环境的配置问题(python java)
    hackintosh和windows时区问题
    CAN波特率计算公式
    Jetson nano 安装 TensorFlow
    python逻辑运算符优先级
    CSS知识点(一)
    HTML标签(二)
    python2与python3的区别
    HTML标签(一)
    IO多路复用和协程
  • 原文地址:https://www.cnblogs.com/mzchuan/p/13589250.html
Copyright © 2020-2023  润新知