Codeforces Round #247 (Div. 2)C. k-Tree(动态规划)
傳送門
Description
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).
Sample Input
3 3 23 3 3
4 3 2
4 5 2
Sample Output
31
6
7
思路
題意:
?給定一個k叉樹,并且邊的權重為1,2,...,k,問有多少條路徑,使得路徑上的邊的權重之和為n,并且這條路徑上至少存在一條邊其權重不小于d。
題解:
首先考慮有多少條路徑,其權重之和為n,用dp[n]代表權重和為n的方案,那么由于是k叉樹,那么dp[n] = dp[n - 1] + dp[n - 2] + ... + dp[n - k];現在考慮路徑上至少有一條邊權重不小于d的情況,用dp[n][1]代表權重之和為1且存在至少一條邊不小于d的方案數,那么dp[n][0]代表權重之和為n且路徑上每一條邊都小于d的方案數。所以當前權重為x時,繼續下一步,那么選擇的邊權為y的分支時,轉移方程:當y < d dp[x + y][0] += dp[x][0] 否則dp[x + y][1] += dp[x][0],不管y 是否大于 d,都有dp[x + y][1] += dp[x][1];
?
#include<bits/stdc++.h> using namespace std; typedef __int64 LL; const int maxn = 105; const int mod = 1e9+7; LL dp[maxn][2];int main() {LL n,k,d;memset(dp,0,sizeof(dp));scanf("%I64d%I64d%I64d",&n,&k,&d);dp[0][0] = 1;for (int i = 0;i <= n;i++){for (int j = 1;j <= k;j++){if (i + j > n) continue;if (j < d) dp[i + j][0] += dp[i][0];else dp[i + j][1] += dp[i][0];dp[i + j][1] += dp[i][1];dp[i + j][0] %= mod;dp[i + j][1] %= mod;}}printf("%I64d\n",dp[n][1]);return 0; }import java.util.*; import static java.lang.System.out;public class KTree {static final int MOD = (int) (1e9+7);public static void main(String[] args){long[][] dp = new long[105][2];int n,k,d;Scanner scan = new Scanner(System.in);n = scan.nextInt();k = scan.nextInt();d = scan.nextInt();dp[0][0] = 1;for (int i = 0;i <= n;i++){for (int j = 1;j <= k;j++){if (i + j > n) continue;if (j < d) dp[i + j][0] += dp[i][0];else dp[i + j][1] += dp[i][0];dp[i + j][1] += dp[i][1];dp[i + j][0] %= MOD;dp[i + j][1] %= MOD;}}out.println(dp[n][1]);} }
?
轉載于:https://www.cnblogs.com/ZhaoxiCheung/p/7287807.html
總結
以上是生活随笔為你收集整理的Codeforces Round #247 (Div. 2)C. k-Tree(动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开奶茶店资金预算 创业之前先准备好本钱
- 下一篇: 万贯街催收流程