• [CF736C](Ostap and Tree)


    • 题意

    给定一个n个点的树,把其中一些点涂成黑色,使得对于每个点,它离与它最近的黑点的距离不超过K,求方案总数.

    • solution

    树形dp

    我们设(dp[i][r])

    状态:当前点为i,离i最近的黑点与i距离为r.

    dp[i][r]的意义: 在i的子树内 达成该状态的方案数

    更新方式当然是递归,让儿子更新父亲,同时把儿子的答案统计到父亲上,这样就把答案汇总到根上了.

    一开始我想的是r取值为0~k,结果是不行的,因为离i最近的黑点不仅可能在i的子树内,还可能在i的子树外

    但我们(在更新dp[i][r]时)只考虑了黑点在i的子树内的情况.

    所以r的取值应该在0~2*k间,这样 即使不合法也要记下来(重要!!) ,因为它子树外的黑点仍然可以使它变成合法的.

    然后我们考虑如何转移

    设v为u的儿子枚举v和u的dp值第二维

    对于dp[u][i]和dp[v][r],我们这样转移

    如果(i+(r+1)<=2 imes k+1)那么(tmp[min(i,r+1)]+=dp[u][i])(tmp为临时数组,转移后赋值到dp[u][i]上,代表u子树内的方案数统计)

    这个方程代表的意思是该方案可行时的转移,然后min(i,r+1)的意思是

    因为这个方案自身的问题已经解决,还(有余力)可以用来更新其他状态,简单的说就是min(i,r+1)代表的那个黑点还可以发挥作用

    如果(i+(r+1)>2 imes k+1)那么(tmp[max(i,r+1)]+=dp[u][i])

    这个方程代表的意思是该方案不可行时的转移,然后max(i,r+1)的意思是

    因为这个方案自身的问题还没解决,需要别的黑点来更新它,

    而因为要更新(使这个方案变得可行)就要照顾到所有点,而其中离黑点最远的点在哪里呢,就是在max(i,r+1)对应的黑点到u的链上,所以我们要把这条链更新,就应该记max(i,r+1)

    r+1是因为从u到v有1的距离

    初始化:dp[u][0]=1(u为黑点)dp[u][k+1]=1(u不为黑点,需要一个距离小于等于k的点来更新它)

    • code

    #include<bits/stdc++.h>
    #define N 205
    #define int long long//懒
    using namespace std;
    const int mod=1e9+7;
    vector<int> G[N];
    int dp[N][N];
    int plk[N];
    int n,k;
    void dfs(int x,int fa){
      dp[x][0]=dp[x][k+1]=1;
      for(int i=0;i<G[x].size();i++){
        int to=G[x][i];
        if(to==fa)continue;
        dfs(to,x);
        for(int i=0;i<=2*k+1;i++)plk[i]=0;
        for(int r=0;r<=2*k+1;r++)
        for(int p=0;p<=2*k;p++){
          if(r+p<=2*k)(plk[min(r,p+1)]+=1ll*dp[x][r]*dp[to][p])%=mod;
          else (plk[max(r,p+1)]+=1ll*dp[x][r]*dp[to][p])%=mod;
          }
        for(int r=0;r<=2*k+1;r++)dp[x][r]=plk[r];
        }
      }
    signed main(){
      scanf("%lld%lld",&n,&k);
      for(int i=1;i<n;i++){
        int a,b;
        scanf("%lld%lld",&a,&b);
        G[a].push_back(b);
        G[b].push_back(a);
        }
      dfs(1,0);
      int ans=0;
      for(int i=0;i<=k;i++)(ans+=dp[1][i])%=mod;
      cout<<ans;
    }
    
  • 相关阅读:
    《JavaScript高级程序设计》笔记:变量、作用域和内存问题(四)
    《JavaScript高级程序设计》笔记:基本概念(三)
    jQ效果:jQuery之插件开发短信发送倒计时功能
    《JavaScript高级程序设计》笔记:在HTML中使用Javascript(二)
    大数据测试大纲
    测试架构师
    大数据的测试思维与探索
    大数据测试
    一个java创建,删除,构建Jenkins等功能的JenkinsUtil工具类
    测试自动化平台 | 测试开发工程师的进阶之路
  • 原文地址:https://www.cnblogs.com/stepsys/p/10488493.html
Copyright © 2020-2023  润新知