【学习笔记】[AGC022F] Checkers

首先不考虑算重,因为这题坑点在于当 n ≥ 5 n\ge 5 n5时不同结构的树可能生成相同的结果。

那么我们考虑生成不同的系数序列 A A A,然后用可重集算一下方案数。考虑将 − 1 -1 1的边缩去后所形成的树,第 i i i层的点表示的是 2 i 2^i 2i,那么如何知道每个节点的正负呢?

请添加图片描述

由瞪眼大法可知,如果 v v v u u u的儿子,那么 v v v会多乘一个系数 2 2 2,说明 v v v是中间点,那么假设 u u u s u s_u su个儿子, u u u的符号就是 ( − 1 ) s u (-1)^{s_u} (1)su。同时如果 u u u有儿子的话,那么其中 ⌈ s u 2 ⌉ \lceil\frac{s_u}{2}\rceil 2su个儿子的符号会变成 u u u符号的相反数, ⌊ s u 2 ⌋ \lfloor\frac{s_u}{2}\rfloor 2su个儿子的符号会和 u u u相同。

据此,我们可以自上往下按层数 d p dp dp。比较棘手的问题在于,它与上一层和下一层的状态都有关。这个坑点很隐蔽啊

然后我借鉴题解 d p i , j dp_{i,j} dpi,j表示 i i i个点形成的树,最下面一层有 j j j个节点有奇数个儿子节点的方案数。枚举下一层的点数 k k k,那么我们知道有 j j j个节点符号和父亲不同,剩下的一半相同,一半不同。我们再枚举实际与父亲相同的个数 p p p,那么下一层至少需要 ∣ k − j 2 − p ∣ |\frac{k-j}{2}-p| 2kjp个有奇数个儿子,也就是可以转移到 d p i + k , ∣ k − j 2 − p ∣ dp_{i+k,|\frac{k-j}{2}-p|} dpi+k,2kjp去。一个错误的想法是,同时转移到 d p i + k , ∣ k − j 2 − p ∣ + 2 w dp_{i+k,|\frac{k-j}{2}-p|+2w} dpi+k,2kjp+2w去,但是这样会算重,因为本质上这一层的状态是相同的。不难证明取最小值可以覆盖所有情况。

重新来看这道题,感觉还是可以给出一个为什么不重不漏的解释的,虽然这个解释非常别扭。考虑对于一个系数序列,对应若干个不同的树,每一个有一个儿子个数为奇数的点的数目,考虑取其中字典序最小的方案,并且要保证同一层为奇数的点全为 0 0 0或者 1 1 1。这样前面的那些转移都说的通了。可以自己试一下。但是我总感觉这是在强行解释,而且没有什么启发性。

复杂度 O ( n 4 ) O(n^4) O(n4)

#include<bits/stdc++.h> #define fi first #define se second #define ll long long #define pb push_back #define inf 0x3f3f3f3f using namespace std; const int mod=1e9+7; int n; ll dp[55][55],fac[55],inv[55]; ll fpow(ll x,ll y=mod-2){ ll z(1); for(;y;y>>=1){ if(y&1)z=z*x%mod; x=x*x%mod; }return z; } void init(int n){ fac[0]=1;for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod; inv[n]=fpow(fac[n]);for(int i=n;i>=1;i--)inv[i-1]=inv[i]*i%mod; } void add(ll &x,ll y){ if((x+=y)>=mod)x-=mod; } ll binom(ll x,ll y){ return fac[x]*inv[y]%mod*inv[x-y]%mod; } signed main(){ cin>>n;init(n); dp[1][0]=dp[1][1]=1; for(int i=1;i<n;i++){ for(int j=0;j<=i;j++){ for(int k=max(j,1);k<=n-i;k++){ if(k-j&1)continue; for(int p=0;p<=k;p++){ add(dp[i+k][abs((k-j)/2-p)],dp[i][j]*inv[p]%mod*inv[k-p]%mod); } } } } cout<<dp[n][0]*fac[n]%mod; }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530051.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示