zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    HDU1879 kruscal 继续畅通工程
    poj1094 拓扑 Sorting It All Out
    (转)搞ACM的你伤不起
    (转)女生应该找一个玩ACM的男生
    poj3259 bellman——ford Wormholes解绝负权问题
    poj2253 最短路 floyd Frogger
    Leetcode 42. Trapping Rain Water
    Leetcode 41. First Missing Positive
    Leetcode 4. Median of Two Sorted Arrays(二分)
    Codeforces:Good Bye 2018(题解)
  • 原文地址:https://www.cnblogs.com/stepsys/p/10488493.html
Copyright © 2011-2022 走看看