Codeforces Round #247(Div. 2) C. k-Tree DP

C. k-Tree
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Quite recently a creative student Lesha had a lecture on trees. After the lecture Lesha was inspired and came up with the tree of his own which he called a k-tree.

A k-tree is an infinite rooted tree where:

  • each vertex has exactly k children;
  • each edge has some weight;
  • if we look at the edges that goes from some vertex to its children (exactly k edges), then their weights will equal 1, 2, 3, ..., k.

The picture below shows a part of a 3-tree.

As soon as Dima, a good friend of Lesha, found out about the tree, he immediately wondered: "How many paths of total weight   n  (the sum of all weights of the edges in the path) are there, starting from the root of a   k-tree and also containing at least one edge of weight at least   d?".

Help Dima find an answer to his question. As the number of ways can be rather large, print it modulo 1000000007 (109 + 7).

Input

A single line contains three space-separated integers: n, k and d (1 ≤ n, k ≤ 100; 1 ≤ d ≤ k).

Output

Print a single integer — the answer to the problem modulo 1000000007 (109 + 7).

Examples
input
3 3 2
output
3
input
3 3 3
output
1
input
4 3 2
output
6
input
4 5 2
output
7

题意:

给定一个k叉树,且是无限有根树,每个节点有k个孩子,从左向右依次编号为1,2,3,...k,每条边有权值,节点连向i号孩子的边的权值为i,问:从根节点开始向下走,有多少条路径满足要求:该路径权值为n,且路径上至少有一条边的权值大于等于d。

题解:

直接求不好求,比较复杂,不过我们可以求出来所以权值为n的路径,然后再减去不符合要求的路径:该路径上所有的边的权值都小于d。

用dp做。

dp[i]:权值为i的路径的条数。

dp2[i]:权值为i的,且路径上的权值都小于d的路径条数。

答案为:dp[n]-dp2[n]


/****************
*PID:431c div2
*Auth:Jonariguez
*****************
dp[i]:权值为i的路径的条数
dp2[i]:权值为i,且路径上的权值都小于d的路径条数
答案:dp[n]-dp2[n]
*/
#define lson k*2,l,m
#define rson k*2+1,m+1,r
#define rep(i,s,e) for(i=(s);i<=(e);i++)
#define For(j,s,e) For(j=(s);j<(e);j++)
#define sc(x) scanf("%d",&x)
#define In(x) scanf("%I64d",&x)
#define pf(x) printf("%d",x)
#define pfn(x) printf("%d\n",(x))
#define Pf(x) printf("%I64d",(x))
#define Pfn(x) printf("%I64d\n",(x))
#define Pc printf(" ")
#define PY puts("YES")
#define PN puts("NO")
#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef int Ll;
Ll quick_pow(Ll a,Ll b,Ll MOD){a%=MOD;Ll res=1;while(b){if(b&1)res=(res*a)%MOD;b/=2;a=(a*a)%MOD;}return res;}

const int maxn=100+10;
const LL MOD=1e9+7;
LL dp[maxn],dp2[maxn];

int main()
{
    int i,j,n,k,d;
    while(scanf("%d%d%d",&n,&k,&d)!=EOF){
        memset(dp,0,sizeof(dp));
        memset(dp2,0,sizeof(dp2));
        dp[0]=1;
        for(i=1;i<=n;i++){
            for(j=1;j<=k;j++){
                if(i-j>=0){
                    dp[i]+=dp[i-j];
                    dp[i]%=MOD;
                }
            }
        }
        dp2[0]=1;
        for(i=1;i<=n;i++){
            for(j=1;j<d;j++){
                if(i-j>=0){
                    dp2[i]+=dp2[i-j];
                    dp2[i]%=MOD;
                }
            }
        }
        LL res=(dp[n]-dp2[n])%MOD;
        if(res<0) res+=MOD;
        printf("%I64d\n",res);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/u013068502/article/details/51065911
今日推荐