zoukankan      html  css  js  c++  java
  • 牛牛与数组(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

    输出描述:

    输出一个整数

    具体思路:

    dp[i][j]表示前i个序列,第i个位j的时候的合法情况。

    如果是三层暴力的话,肯定会T,我们可以记录第二个for循环的总值,然后再去把不符合的情况给去掉。如果条件1,我们累加这个数前面的数就好了。

    对于条件2,我们先预处理出来每个数的倍数,然后再减去不合法的情况就可以了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 const int maxn = 2e5+100;
     6 const int  N = 15;
     7 const int mod = 1e9+7;
     8 ll dp[N][maxn];
     9 vector<ll>sto[maxn];
    10 int main(){
    11 int n,k;
    12 scanf("%d %d",&n,&k);
    13 for(int i=1;i<=k;i++){
    14 dp[1][i]=1;
    15 }
    16 for(int i=1;i<=k;i++){
    17 for(int j=2;j*i<=k;j++){
    18 sto[i].push_back(i*j);
    19 }
    20 }
    21 for(int i=2;i<=n;i++){
    22 ll sum=0;
    23 for(int j=1;j<=k;j++){sum=(sum+dp[i-1][j])%mod;}
    24 ll tmp=0;
    25 for(int j=1;j<=k;j++){
    26 dp[i][j]=(dp[i-1][j]+tmp)%mod;
    27 tmp=(tmp+dp[i-1][j])%mod;
    28 ll ans=(sum-tmp+mod)%mod;// 把已经算过的情况给删除
    29 for(int w=0;w<sto[j].size();w++){
    30 ans=(ans-dp[i-1][sto[j][w]]+mod)%mod;
    31 }
    32 dp[i][j]=(dp[i][j]+ans)%mod;
    33 }
    34 }
    35 ll ans=0;
    36 for(int i=1;i<=k;i++){
    37 ans=(ans+dp[n][i])%mod;
    38 }
    39 printf("%lld
    ",ans);
    40 return 0;
    41 }
  • 相关阅读:
    C++11新特性
    Qt操作xml
    指针和引用的区别
    QT软件主题切换
    常见的临时变量的生成场景
    QQuickWidget+QML设置背景透明
    idea maven Could not transfer artifact
    Java项目启动时执行指定方法的几种方式
    解决bootstrap-table在切换分页后再次查询报错404问题
    bootstrap:表单必填项*标识,及提交前校验
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10966724.html
Copyright © 2011-2022 走看看