• 855C Helga Hufflepuff's Cup


    传送门

    题目大意

    给你一棵树,可以染m种颜色,现定义一种特殊的颜色K,一棵树上最多能有x个特殊颜色。如果一个节点为特殊颜色,那么他相邻的节点的值只能选比K小的颜色,问一共有多少种染色方案。

    分析

    不难想出这是一个树型dp,用dp[i][j][k]表示考虑第i个点所选的颜色的种类为j,共用了k个特殊颜色。j的状态分别是0代表[1,K-1],1代表[K+1,m],2代表K。然后我们考虑如何转移。首先我们不难想到对于每种状态它是由之前哪种状态转移来的(见代码),对于k的枚举我们可以依次考虑一个点的所有儿子,然后每一次用当前儿子的值更新这个点的dp值。我们假设之前所有儿子和这个点自己一共选了k1个特殊颜色,而这个儿子及其子树选了k2个特殊颜色,这样就可以转移了。详见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define li long long
    const li mod = 1e9+7;
    li n,m,x,sum,dp[101000][3][12],now[3][12];
    vector<li>v[101000];
    inline void dfs(li a,li fa){
          dp[a][0][0]=m-x;
          dp[a][1][0]=x-1;
          dp[a][2][1]=1;
          for(li i=0;i<v[a].size();i++)
            if(v[a][i]!=fa){
              dfs(v[a][i],a);
              memset(now,0,sizeof(now));
              for(li k=0;k<=sum;k++)
                for(li k2=0;k2+k<=sum;k2++){
                    now[0][k+k2]=(now[0][k+k2]+(dp[a][0][k]*
                    (dp[v[a][i]][0][k2]+dp[v[a][i]][1][k2]))%mod)%mod;
                  now[1][k+k2]=(now[1][k+k2]+(dp[a][1][k]*(dp[v[a][i]][0][k2]
                    +dp[v[a][i]][1][k2]+dp[v[a][i]][2][k2])%mod))%mod;
                  now[2][k+k2]=(now[2][k+k2]+
                    (dp[a][2][k]*dp[v[a][i]][1][k2]%mod))%mod;
                }
              for(li k=0;k<=sum;k++){
                dp[a][0][k]=now[0][k];
                dp[a][1][k]=now[1][k];
                dp[a][2][k]=now[2][k];
              }
            }
          return;
    }
    int main(){
          li i,j,k;
          scanf("%lld%lld",&n,&m);
          memset(dp,0,sizeof(dp));
          for(i=1;i<n;i++){
              li a,b;
              scanf("%lld%lld",&a,&b);
              v[a].push_back(b);
              v[b].push_back(a);
          }
          scanf("%lld%lld",&x,&sum);
          dfs(1,0);
          li ans=0;
          for(i=0;i<3;i++)
            for(j=0;j<=sum;j++)
              ans=(ans+dp[1][i][j])%mod;
          printf("%lld
    ",ans);
          return 0;
    }
  • 相关阅读:
    JQuery实现1024小游戏
    Windows Server2008 R2安装wampserver缺少api-ms-win-crt-runtime-l1-1-0.dll解决方案
    ASP.NET MVC 邮件发送的功能(微软邮箱发送)。
    浅谈撞库防御策略
    极验高并发验证服务背后的技术实现
    2015年国内数据安全事件盘点
    转载——验证码的昨天、今天和明天
    转载——最近百度云盘不提供搜索,闲来无事,玩玩python爬虫,爬一下百度云盘的资源
    SQL 查询语句
    SQL Server 目录
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9490192.html
Copyright © 2020-2023  润新知