首页 > 其他分享 >2022.11.14模拟赛题解

2022.11.14模拟赛题解

时间:2022-11-16 11:44:19浏览次数:75  
标签:tmp sz 14 题解 sum t2 t1 2022.11 dp

树的覆盖

\(dp_{i,j,0/1/2}\) 表示以 \(i\) 为根的子树中覆盖 \(j\) 个点的方案数。其中 \(0/1/2\) 分别表示了 \(3\) 种情况。

  • \(0\) 表示示当前节点和子节点都没被选中
  • \(1\) 表示当前节点被选中,子节点选中与不选中都归于这一类
  • \(2\) 表示存在子节点被选中且当前节点不选中

考虑 \(\rm dp\) 转移

枚举已遍历子树中选择几个,再枚举正在遍历的子树中选择几个,根据乘法原理相乘即可。

核心代码:

for (auto v : E[x]) {
    if (v == fa) continue;
    dfs(v, x);
    R(i, 0, sz[x]) {
        R(j, 0, sz[v]) {
            R(t1, 0, 2) {
                R(t2, 0, 2) {
                    int sum = i + j, p = t1;
                    if (!t1 && t2 == 1) p = 2, ++sum;
                    if (t1 == 1 && !t2) ++sum;
                    tmp[sum][p] += dp[x][i][t1] * dp[v][j][t2];
                    tmp[sum][p] %= P;
                }
            }
        }
    }
    sz[x] += sz[v];
    R(i, 0, sz[x]) {
        R(j, 0, 2) {
            dp[x][i][j] = tmp[i][j];
            tmp[i][j] = 0;
        }
    }
}

其中 \(sum\) 表示在已遍历子树与正在遍历的子树的选择下会在 \(x\) 的子树中覆盖几个点。
在这里你会发现一些变化,if (!t1 && t2 == 1) p = 2, ++sum; !t1 的意思是 \(x\) 不选且它没有儿子选中,然而 t2==1 的意思是 \(x\) 的正在遍历的点要选,所以两个状态矛盾,现在的状态变为了 \(x\) 不选且它有儿子要选,变为状态 \(2\)。两个 ++sum 的意思是有一个点选了而它相邻的点没选,所以覆盖的总数要 \(+1\)。
还有一个细节,代码中用了一个临时数组来存储当前的 \(dp\),否则会用到现在的信息就会发生错误。

几乎完整的代码:

const int N = 2005, P = 1e9 + 7;
int n, sz[N], dp[N][N][3], tmp[N][3];
vector <int> E[N];
void dfs(int x, int fa) {
    sz[x] = 1;
    dp[x][1][1] = dp[x][0][0] = 1;
    for (auto v : E[x]) {
        if (v == fa) continue;
        dfs(v, x);
        R(i, 0, sz[x]) {
            R(j, 0, sz[v]) {
                R(t1, 0, 2) {
                    R(t2, 0, 2) {
                        int sum = i + j, p = t1;
                        if (!t1 && t2 == 1) p = 2, ++sum;
                        if (t1 == 1 && !t2) ++sum;
                        tmp[sum][p] += dp[x][i][t1] * dp[v][j][t2];
                        tmp[sum][p] %= P;
                    }
               }
            }
        }
        sz[x] += sz[v];
        R(i, 0, sz[x]) {
            R(j, 0, 2) {
                dp[x][i][j] = tmp[i][j];
                tmp[i][j] = 0;
            }
        }
    }
}
signed main() {
    read(n);
    R(i, 1, n - 1) {
        int u, v;
        read(u, v);
        E[u].pb(v), E[v].pb(u);
    }
    dfs(1, 0);
    int ans = 0;
    R(i, 0, n) {
        ans = dp[1][i][0] + dp[1][i][1] + dp[1][i][2]; ans %= P;
        write(ans), ptc('\n');
    }
    return 0;
}

标签:tmp,sz,14,题解,sum,t2,t1,2022.11,dp
From: https://www.cnblogs.com/cyyhcyyh/p/16895360.html

相关文章

  • CSP 201403-1 相反数 C++
    1#include<iostream>2#include<vector>3#include<algorithm>45intmain(){6intx{},sum{};7std::cin>>x;8std::vector<int>n(......
  • CF1748D ConstructOR 题解
    可能更好的食用体验既然题目中用到了位运算,那我们就用二进制来解决这道题。1.判无解观察\(3\,4\,6\)这个样例,我们将其分解二进制:\[\begin{aligned}(3)_{10}&=(11)......
  • 洛谷 P8509 题解(待完善)
    题面。要求所有点到关键点的距离和最小。首先要确定这个点去哪个关键点最短。树上两点间路径与距离是唯一的,所以我们从两个关键点分别跑dfs。第一遍求出每个点到s的最......
  • Python 文本文件拖上转自适应图片 - 学习笔记(2022.11.16)
    Python文本文件拖上转自适应图片功能:1、支持拖拽执行2、文本文件转为自适应尺寸图片1importre2importos3importsys4importtime5fromPI......
  • MYSQL ERROR 1146 Table doesnt exist 解析
    原创转载请注明出处源码版本5.7.14在MYSQL使用innodb的时候我们有时候会看到如下报错:ERROR1146(42S02):Table'test.test1bak'doesn'texist首先总结下原......
  • 【2022.11.15】luffy项目部署(9)
    内容概要1redis字符串操作2redishash操作3redis列表操作4redis管道5redis其他操作6django中集成redis7celery介绍内容详细#装了图形化客户......
  • 2211-14MongoDB学习
    学习资源来自菜鸟教程MongoDB数据库MongoDB概念解析不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍。下......
  • 神奇脑洞题解——USACO追查坏牛奶(CSGO894)
    COGS的这一题是超级满配版本比洛谷的要强力的多:894.追查坏牛奶-COGS额外要求是:求出最小割流量,同时求出割边最小,同时字典序最小的方案输出割掉的边最小割流量好求,最......
  • 【题解】[模拟赛20221115] Tree
    模拟赛20221115Tree|CQNK\(O(m*n*2^n)\)很好做,但是本题有更优秀的做法:在此记录复杂度\(O(n*2^n)\)的做法。考虑从后往前dp,设dp状态\(f_{s,0/1}\)分别表示在填......
  • 14.循环
    种类......