zoukankan      html  css  js  c++  java
  • 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)

    题意与分析(Codeforces-431C)

    题意是这样的:给出K-Tree——一个无限增长的树,它的每个结点都恰有(K)个孩子,每个节点到它(K)个孩子的(K)条边的权重各为(1,2,...,K),问现有多少条路径,使从根节点出发到某个结点所经过的边权重之和恰为n,且经过的边至少有一条权重不小于(d)
    我们来考虑一下阶段:一层一层的走下去——这个是显然的。而状态是什么?影响我们答案(路径条数)的只有一个,权重的和,它是由我们底下的若干个孩子所走的权重和的情况的和构成的。从某个节点走到某个节点改变了什么?当我走了一条边i,我就还剩(n-i)的权重需要走了。而我有(k)个边,因此对于一个K-Tree的某个点(每个点是等价的,所以决定性因素只能是和),如果它还剩(n)的权重和没有走,那么它的状态转移方程就是(dp[n-1]+dp[n-2]+...+dp[n-k]=dp[n])。这样就能求出没有限制条件下的路径个数。
    然后考虑一下限制条件。不小于(d),很自然地会觉得有点困难去实现。于是想到正难则反,我们求出所有边权重小于d的情况就行了——也就是(k=d-1)。而同样的,不改变的是预先的权重和(n),因此再次运用上面的状态转移方程,然后把(k)代入为(d-1)即可。二者最后相减即可。

    代码

    注意减法操作时候的取模。

    #include <bits/stdc++.h>
    using namespace std;
    
    const long long mod=1e9+7;
    long long dpa[105], dpb[105];
    int main()
    {
    	int n,k,d; cin>>n>>k>>d;
    	dpa[0]=dpb[0]=1;
    	for(int i=1;i<=n;++i)
    	{
    		for(int j=1; j<=k && i-j>=0; ++j)
    		{
    			dpa[i]=(dpa[i]+dpa[i-j])%mod;
    		}
    	}
    	for(int i=1;i<=n;++i)
    	{
    		for(int j=1; j<=d-1 && i-j>=0; ++j)
    		{
    			dpb[i]=(dpb[i]+dpb[i-j])%mod;
    		}
    	}
    	cout<<(dpa[n]-dpb[n]+mod)%mod<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Go Revel
    Go Revel
    Go Revel
    Go Revel
    deployment:声明式的升级应用
    Kubernetes架构及相关服务详解
    Docker 安装MySQL
    日志收集-Elk6
    Jenkins-Multijob plugin多任务串并行
    ansible创建vmware虚拟机
  • 原文地址:https://www.cnblogs.com/samhx/p/CFR247D2C.html
Copyright © 2011-2022 走看看