object cf431C {
val MOD:Int = 1000000007
def main(args : Array[String]) : Unit = {
val sc = new Scanner(System.in)
val n,k,d = sc.nextInt
val dp = Array.ofDim[Int](105, 2)
dp(0)(0) = 1
for(i <- 0 until n; j<- 0 to 1;r<- 1 to k){
if(i+r<=n){
val flag = if(j==1 || r>=d) 1 else 0
dp(i+r)(flag) = (dp(i)(j)+dp(i+r)(flag))% MOD
}
}
println(dp(n)(1))
}
}
常规的类最长子序列动态规划,
第一步:设dp[i][j] 表示长度路径权重和为j,并且路径中最大的节点权重为j的条数。
那么从根节点出发的路径可以初始为1,即dp[0][0] = 1
第二步:动态转移方程dp[i][j>r?j:r] = dp[i-r][r]+dp[i][>r?j:r] ( r<=i<=n,1<=r<=k)
第三步:求和。题意中的不少于路径中最大权重节点不小于d,所以answer = sum(dp[n][n<=t<=k])
简化转移方程:
事实上dp的状态只有两种即路过的结点权重不小于d,或者小于d。把这个算作两种状态。
转移方程即可转化为dp[i][ r>d || j ?]+=dp[i-r][j] (r<=i<=n,j@(0,1),1<=r<=k)