zoukankan      html  css  js  c++  java
  • [bzoj4813][Cqoi2017]小Q的棋盘

    来自FallDream的博客,未经允许,请勿转载,谢谢。


    小Q正在设计一种棋类游戏。在小Q设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。n,v<=100

    很明显是sb树形dp啊,但是这数据范围.....

    f[0/1][i][j]第i个节点,走了j次,回不回根节点最大答案,很好转移。

    我是不会告诉你们我对着这sb题猛wa了几次的

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MN 100
    using namespace std;
    int X;char ch;
    inline int read()
    {
        X = 0 , ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9')X = X * 10 + ch - '0',ch = getchar();
        return X;
    }
    
    int f1[MN+5][MN+5],f2[MN+5][MN+5],cnt=0,n,m,ans=0,head[MN+5];
    struct edge{int to,next;}e[MN*2+5];
    
    inline void ins(int f,int t)
    {
        e[++cnt]=(edge){t,head[f]};head[f]=cnt;
        e[++cnt]=(edge){f,head[t]};head[t]=cnt;
    }
    
    void dfs(int x,int fa)
    {
        f1[x][0]=f2[x][0]=1;
        for(int i=head[x];i;i=e[i].next)
            if(e[i].to!=fa)
            {
                dfs(e[i].to,x);
                for(int j=m;j;j--)
                    for(int k=0;k<j;k++)
                    {
                        if(k<j-1)f1[x][j]=max(f1[x][j],f1[e[i].to][k]+f1[x][j-k-2]),
                                 f2[x][j]=max(f2[x][j],f1[e[i].to][k]+f2[x][j-k-2]);
                        f2[x][j]=max(f2[x][j],f2[e[i].to][k]+f1[x][j-k-1]);
                    }
            }
    }
    
    int main()
    {
        n=read();m=read();
        for(register int i=1;i<n;i++)ins(read()+1,read()+1);
        dfs(1,0);
        for(register int j=0;j<=m;j++)
             ans=max(ans,f2[1][j]);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    加一
    斐波那契数
    整数的各位积和之差
    移除元素
    删除排序数组中的重复项
    有效的括号
    爬楼梯
    最长公共前缀
    罗马数字转整数
    回文数
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj4813.html
Copyright © 2011-2022 走看看