小易喜欢的数列
题目描述
小易非常喜欢拥有以下性质的数列:
1、数列的长度为n
2、数列中的每个数都在1到k之间(包括1和k)
3、对于位置相邻的两个数A和B(A在B前),都满足(A <= B)或(A mod B != 0)(满足其一即可)
例如,当n = 4, k = 7
那么{1,7,7,2},它的长度是4,所有数字也在1到7范围内,并且满足第三条性质,所以小易是喜欢这个数列的
但是小易不喜欢{4,4,4,2}这个数列。小易给出n和k,希望你能帮他求出有多少个是他会喜欢的数列。
1、数列的长度为n
2、数列中的每个数都在1到k之间(包括1和k)
3、对于位置相邻的两个数A和B(A在B前),都满足(A <= B)或(A mod B != 0)(满足其一即可)
例如,当n = 4, k = 7
那么{1,7,7,2},它的长度是4,所有数字也在1到7范围内,并且满足第三条性质,所以小易是喜欢这个数列的
但是小易不喜欢{4,4,4,2}这个数列。小易给出n和k,希望你能帮他求出有多少个是他会喜欢的数列。
很基本的动态规划问题:
dp[i][j]保存以j结尾的数列长度为i的符合条件的数列的个数
先求出所有长度为i-1的满足条件的数列的个数和
再去掉不满足条件的那部分
主要排除的是前一位i-1位末尾能够能够整除i位的这种情况
public class Main { static final int mod = 1000000007; public static void main(String[] args) { Scanner scan=new Scanner(System.in); int n=scan.nextInt(); int k=scan.nextInt(); int[][] dp=new int[n+1][k+1]; dp[0][1]=1; for(int i=1;i<=n;i++) { int sum=0; for(int j=1;j<=k;j++) { sum=(sum+dp[i-1][j])%mod; } for(int j=1;j<=k;j++) { int p=2; int invalid=0; while(j*p<=k) { invalid=(invalid+dp[i-1][j*p])%mod; p++; } dp[i][j]=(sum-invalid)%mod; } } int sum=0; for(int i=1;i<=k;i++) { sum=(sum+dp[n][i])%mod; } System.out.println(sum); } }
时间复杂度O(n*k*logk)
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/10851821.html

浙公网安备 33010602011771号