zoukankan      html  css  js  c++  java
  • gmoj 6810. 【2020.10.05提高组模拟】路哥

     

    这道题是一道树形dp,设f[i][j]表示到第i个点,此时权值和为j的期望值。

    一开始打的是n^3的暴力,但是因为数据水所以拿了60分。

    这道题的正解就是暴力优化,树形依赖dp。

    因为选每一个点的条件是选了这个点到根节点的所有点,所以可以在dp到这个点的儿子之前,将这个点的dp值传下去,因为此时相当于是只多增加了一个点,所以可以O(k)做。

    做完这个点以后,再将这个点的dp值传回去,同时计算断掉这条边的情况,这个也是O(k)的。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 5010
    #define K 5010
    #define ll long long
    #define mo 998244353
    #define er 499122177
    using namespace std;
    int n,k,i,f[N][K],q[N],sum[N],x,y,tot,g[N][K];
    ll temp;
    struct edge{
        int to,next;
    }e[N*2];
    void insert(int x,int y){
        tot++;
        e[tot].to=y;
        e[tot].next=q[x];
        q[x]=tot;
    }
    void dfs(int x,int father){
        int i,j,l,y;
        for (i=q[x];i;i=e[i].next){
            y=e[i].to;
            if (y!=father){    
                for (j=0;j<=k;j++){
                    if (j+sum[y]<=k)
                        temp=1ll*f[x][j]*er%mo,f[y][j+sum[y]]=temp;
                }
                dfs(y,x);
                for (j=0;j<=k;j++)
                    temp=1ll*(f[y][j]+1ll*f[x][j]*er%mo)%mo,f[x][j]=temp;
            }
        }
    }
    int main(){
        freopen("luge.in","r",stdin);
        freopen("luge.out","w",stdout);
        scanf("%d%d",&n,&k);
        for (i=1;i<=n;i++) scanf("%d",&sum[i]);
        for (i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            insert(x,y);
            insert(y,x);
        }
        f[1][sum[1]]=1;
        dfs(1,0);
        printf("%d
    ",f[1][k]);
        return 0;
    }
  • 相关阅读:
    高校教师职评
    高校教师曝职评内幕:混行政圈比科研圈更重要
    【50.88%】【Codeforces round 382B】Urbanization
    【64.22%】【codefoces round 382A】Ostap and Grasshopper
    【u253】售货厅
    【u250】manhattan
    【19.77%】【codeforces 570D】Tree Requests
    【t063】最聪明的机器人
    Java Web整合开发(38) -- Log4J
    公网 or 内网
  • 原文地址:https://www.cnblogs.com/Mohogany/p/13771728.html
Copyright © 2011-2022 走看看