Codeforces 414B Mashmokh and ACM(DP)

Mashmokh‘s boss, Bimokh, didn‘t like Mashmokh. So he fired him. Mashmokh decided to go to university and participate in ACM instead of finding a new job. He wants to become a member of Bamokh‘s team.
In order to join he was given some programming tasks and one week to solve them. Mashmokh is not a very experienced programmer. Actually he is not a programmer at all. So he wasn‘t able to solve them. That‘s why he asked you to help him with these tasks. One
of these tasks is the following.

A sequence of l integers b1,?b2,?...,?bl (1?≤?b1?≤?b2?≤?...?≤?bl?≤?n) is
called good if each number divides (without a remainder) by the next number in the sequence. More formally  for
all i (1?≤?i?≤?l?-?1).

Given n and k find the number of good sequences of
length k. As the answer can be rather large print it modulo 1000000007 (109?+?7).

Input

The first line of input contains two space-separated integers n,?k (1?≤?n,?k?≤?2000).

Output

Output a single integer — the number of good sequences of length k modulo 1000000007 (109?+?7).

Sample test(s)

input

3 2

output

5

input

6 4

output

39

input

2 1

output

2

Note

In the first sample the good sequences are: [1,?1],?[2,?2],?[3,?3],?[1,?2],?[1,?3].

题目就是有关计数问题的DP;

设dp[i][j]表示以i为结尾长度为j的方案数:dp[i][j]=sum(dp[k][j-1])(i%k==0)

特别的dp[i][1]=1;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int MOD=1e9+7;
const int maxn=2000+100;
LL dp[maxn][maxn];
int n,k;

int main()
{
    while(cin>>n>>k)
    {
        CLEAR(dp,0);
        REPF(i,1,n)  dp[i][1]=1;
        for(int j=1;j<=n;j++)
          for(int kk=j;kk<=n;kk+=j)
            for(int i=2;i<=k;i++)
              dp[kk][i]=(dp[kk][i]+dp[j][i-1])%MOD;
        LL ans=0;
        REPF(i,1,n)
           ans=(ans+dp[i][k])%MOD;
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-11-06 07:10:52

Codeforces 414B Mashmokh and ACM(DP)的相关文章

CodeForces 414B - Mashmokh and ACM

给你长度为 l 的整数数列b1, b2, ..., bl(1 ≤ b1 ≤ b2 ≤ ... ≤ bl ≤ n) 如果这个数列被称为好的,那么每个元素都可以整除下一个元素 给你n和k,去找到长度为k的好数列的个数 dp[任意i][1] = 1: dp[i的倍数][长度k] = dp[i][长度k-1] + 1; 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int MOD = 100

codeforces 414B B. Mashmokh and ACM(dp)

题目链接: codeforces 414B 题目大意: 定义一个序列,前一项能够整除后一项,给定这个序列中数的取值范围和序列的长度,问有多少种构造方法. 题目分析: 我们定义状态dp[i][j]为前i项已经确定且第i项为j的方案数. 转移方程 dp[i][j]=∑k|jdp[i?1][k] 复杂度O(n?k) AC代码: #include <iostream> #include <cstring> #include <algorithm> #include <cs

Codeforces Round #240 (Div. 1)---B.Mashmokh and ACM(dp)

Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university and participate in ACM instead of finding a new job. He wants to become a member of Bamokh's team. In order to join he was given some programming tas

Codeforces Gym101341K:Competitions(DP)

http://codeforces.com/gym/101341/problem/K 题意:给出n个区间,每个区间有一个l, r, w,代表区间左端点右端点和区间的权值,现在可以选取一些区间,要求选择的区间不相交,问最大的权和可以是多少,如果权和相同,则选区间长度最短的.要要求输出区间个数和选了哪些区间. 思路:把区间按照右端点排序后,就可以维护从左往右,到p[i].r这个点的时候,已经选择的最大权和是多少,最小长度是多少,区间个数是多少. 因为可以二分找右端点小于等于当前区间的左端点的某个区间

Codeforces 1051 D.Bicolorings(DP)

Codeforces 1051 D.Bicolorings 题意:一个2×n的方格纸,用黑白给格子涂色,要求分出k个连通块,求方案数. 思路:用0,1表示黑白,则第i列可以涂00,01,10,11,(可以分别用0,1,2,3表示),于是定义dp[i][j][k]:涂到第i列分为j个连通块且第i列涂法为k的方案数,则有了代码中的转移式,共16种转移类型. #include<iostream> #include<cstdio> #include<algorithm> #in

Codeforces 803E--Roma and Poker (DP)

原题链接:http://codeforces.com/problemset/problem/803/E 题意:给一个n长度的字符串,其中'?'可以替换成'D'.'W'.'L'中的任意一种,'D'等价于0, 'W'等价于1.'L'等价于-1.输出所有'?'被替换掉后,W和L的数目之差为k,且任意一个[1, i]的子串中W和L数目之差不能等于k. 思路:用DP做.定义bool dp[i][j]代表前i个字符W和L数目之差为j, -k<=j<=k(在数组中范围为[0, 2*k]),那么当str[i]

Codeforces 543C Remembering Strings(DP)

题意比较麻烦 见题目链接 Solution: 非常值得注意的一点是题目给出的范围只有20,而众所周知字母表里有26个字母.于是显然对一个字母进行变换后是不影响到其它字符串的. 20的范围恰好又是常见状压DP的范围,所有状态压缩后用DP[sta]代表对应位的字符串已经满足要求的最小花费. 转移的时候,对一个字符串,逐列判断使它满足条件的最小花费,记录使用这个策略对sta的影响. 即对同一列有两种情况,直接变换该字符串的这一位,或者变换这一列的sum-1个有相同字符的位置(去掉代价最大的). #in

Codeforces 543D Road Improvement(DP)

题目链接 Solution 比较明显的树形DP模型. 首先可以先用一次DFS求出以1为根时,sum[i](以i为子树的根时,满足要求的子树的个数). 考虑将根从i变换到它的儿子j时,sum[i]产生的变化. 在变化前sum[i]不为0时,可以用求逆元的方法求出新的sum[i]. sum[i]为0时,就需要遍历i的新的儿子. 官方的题解给出了一个比较好的做法是预处理i的儿子的前缀积,和后缀积.使用的时候只要去除相应的儿子. #include <bits/stdc++.h> #define LL

cf 414B Mashmokh and ACM 动态规划

题目链接:http://codeforces.com/problemset/problem/414/B dp[i][j]表示长度为i.最后一个数字为j的合法序列总数 dp[1][1...2000]都是1 后面用dp[i-1][j] 去更新 dp[i][j*t] (1 <= j*t <= 2000) 即用因子去更新它的倍数 表面上看是2000^3的复杂度会爆 其实不用算那么多次 最外层循环是2000 分析第二层和第三层 需要算 2000/1 + 2000/2 + 2000/3 + 2000/4