TopCoder SRM 548 1000分 dp+组合数
2017-10-15 20:50
218 查看
题意
给出n,m,k,求出具有n个点、m条边、且前k个点的点度恰好为2的无向连通图个数,答案对109+7取模。数据范围
n,m≤50,k≤2解法
首先简化题目,我们考虑k=0的时候,那么有一个很经典的做法是DP。我们用dp[i][j]表示i个点m条边的连通图个数,那么答案明显是dp[n][m]。接下来的转移我们考虑补集转化,我们枚举1号点所在的联通块点数和边数,那么
dp[i][j]=CjC2i−∑i−1k=1∑min(j,C2k)l=k−1dp[k][l]∗Ck−1i−1∗Cj−lC2i−k
那么我们已经完美解决了k=0的情况,接下来我们分析一下k=1的情况,由于1号点的度数为2,那么我们可以得出,删掉1号点及其连边,剩余的图要么只有1个联通块要么只有2个联通块。
对于只有1个联通块的情况,明显就是
dp[n−1,m−2]∗C2n−1
对于有2个联通块的情况,我们依然可以枚举2号点所在的联通块大小及边数,答案就是
∑n−2i=1∑min(C2i,m−2)j=i−1dp[i][j]∗dp[n−1−i][m−2−j]∗i∗(n−1−i)∗Ci−1n−2
于是k=1的情况也被解决了 作为一条咸鱼,我选择放弃k=2
其实k=2和k=1的情况差不多,只不过要讨论的情况变多了而已。说的简单啊喂
那么我们将1号点和2号点提出来,发现其余点和边构成的图的联通块个数只有1,2,3个。
当1号点与2号点相连的时候,联通块只可能为1或者2。
若联通块为1,那么答案就是
dp[n−2][m−3]∗(n−2)∗(n−2)
若联通块为2,其实也就等于了k=1的情况,不过我们要把答案×2,因为跟1号点连边和2号点连边是两种不同的情况。
2∗∑n−3i=1∑min(C2i,m−3)j=i−1dp[i][j]∗dp[n−2−i][m−3−j]∗i∗(n−2−i)∗Ci−1n−3
当1号点与2号点不相连的时候,若联通块个数为1,那么答案就是
dp[n−2][m−4]∗C2n−2∗C2n−2
若联通块个数为2,我们就枚举3号点所在的联通块大小及边数,那么答案是 啊公式真的好难打
∑n−3i=1∑min(C2i,k−4)j=i−1dp[i][j]∗dp[n−2−i][m−4−j]∗Ci−1n−3∗i∗(n−2−i)∗(2∗(C2i+C2n−2−i)+i∗(n−2−i) )
最后的那个括号里面的表示1个点连接两个联通块,另一个点要么两条边都在同一个联通块内,要么也连接两个联通块,注意后面的不×2。
若联通块个数为3,那么很明显1 2号线都要连接两个联通块,这时候我们枚举第1个联通块(设为K1),第二个联通块(K2)的点数和边数,那么第三个联通块(k3)的点数和边数也就确定了。说实话我觉得这个公式我要打半小时
∑n−4v1=1∑min(C2v1,m−4)e1=v1−1dp[v1][e1]∗Cv1n−2
∑v1+v2<=n−3v2=1∑min(C2v2,m−e1−4)e2=v2−1dp[v2][e2]∗Cv2n−2−v1
dp[n−2−v1−v2][m−4−e1−e2]
v1∗v2∗(n−2−v1−v2)∗(n−2)∗2
以上4行就是计算答案的过程了(自动在换行处补*)
最后那个式子v1*v2*(n-2-v1-v2)*(n-2)*2是这样算的,我们枚举1号点连接的两个联通块的方案数,再枚举2号点的,那么就有式子
v1∗v2∗(v1∗v3+v2∗v3)+v1∗v3∗(v1∗v2+v2∗v3)+v2∗v3∗(v1∗v2+v1∗v3)
合并一下就是
v1∗v2∗v3∗(v1+v2+v3)∗2=v1∗v2∗v3∗(n−2)∗2
到此为止这道题也就完美解决了
收获
这个题的入手点就是我们发现k很小,只有三种情况。那么我们从简到难,先发现k=0的情况可以由DP解决。
再由限制的度数为2来推出除去限制点以外的联通块个数不会太多,于是我们分类讨论情况就可以了。
考点:
组合数 DP易错点:
漏情况 边界(这个其实可以用一些技巧忽视掉) 少取膜一个月以内我不会再写一篇公式这么多的题解了QAQ
#define mN 2510 #define mod 1000000007 #define ms(a,b) memset(a,b,sizeof(a)) #define ll long long #define min(a,b) (a<b?a:b) class KingdomAndCities { public: ll c[mN][61]; ll dp[61][61]; int howMany(int n, int k, int m) { ms(c,0); c[0][0]=1; if (m<n-1) return 0; for (int i=1; i<=n*n; i++) { c[i][0]=1; for (int j=1; j<=i; j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; } ms(dp,0); for (int i=1; i<=n; i++) for (int j=i-1; j<=min(c[i][2],m); j++) { dp[i][j]=c[c[i][2]][j]; for (int k=1; k<=i-1; k++) for (int l=k-1; l<=min(c[k][2],j); l++) dp[i][j]=(dp[i][j]-dp[k][l]*c[i-1][k-1]%mod*c[c[i-k][2]][j-l]%mod+mod)%mod; } if (k==0) return dp [m]%mod; if (k==1) { int ans=0; ans+=dp[n-1][m-2]*c[n-1][2]%mod; for (int i=1; i<=n-2; i++) for (int j=i-1; j<=min(c[i][2],m-2); j++) { ans=(ans+dp[i][j]*dp[n-1-i][m-2-j]%mod*i%mod*(n-1-i)%mod*c[n-2][i-1]%mod)%mod; } return ans%mod; } if (k==2) { int ans=0; ans=dp[n-2][m-3]*(n-2)%mod*(n-2)%mod; for (int i=1; i<=n-3; i++) for (int j=i-1; j<=min(c[i][2],m-3); j++) { ans=(ans+2*dp[i][j]%mod*dp[n-2-i][m-3-j]%mod*i%mod*(n-2-i)%mod*c[n-3][i-1]%mod)%mod; } ans=(ans+dp[n-2][m-4]*c[n-2][2]%mod*c[n-2][2]%mod)%mod; for (int i=1; i<=n-3; i++) for (int j=i-1; j<=min(c[i][2],m-4); j++) { ans=(ans+dp[i][j]*dp[n-2-i][m-4-j]%mod*i%mod*(n-2-i)%mod*c[n-3][i-1]%mod*((2*(c[i][2]+c[n-2-i][2])%mod+i*(n-2-i)%mod)%mod)%mod)%mod; } for (int v1=1; v1<=n-4; v1++) for (int e1=v1-1; e1<=min(c[v1][2],m-4); e1++) for (int v2=1; v1+v2<=n-3; v2++) for (int e2=v2-1; e2<=min(c[v2][2],m-e1-4); e2++) ans=(ans+dp[v1][e1]*c[n-3][v1-1]%mod*dp[v2][e2]%mod*c[n-3-v1][v2-1]%mod*dp[n-2-v1-v2][m-4-e1-e2]%mod*v1%mod*v2%mod*(n-2-v1-v2)%mod*(n-2)%mod*2%mod)%mod; return ans; } return 0; } };
相关文章推荐
- [容斥] Topcoder SRM div1-3 12004. SetAndSet
- TopCoder SRM 633 Div.2 500 Jumping
- 第一次参加Topcoder SRM
- [Topcoder&nbsp;SRM&nbsp;467]均匀字符串Next…
- Topcoder SRM 656 DIV2 1000 题解(动态规划)
- Topcoder SRM 573 WolfPackDivTwo
- 记首次参加TopCoder SRM Match,SRM 582
- topcoder SRM495 div1 level3
- Topcoder srm log
- topcoder SRM div 2 level 1
- TopCoder SRM 649 Div2 Problem 500 - CartInSupermarketEasy (区间DP)
- TopCoder SRM 659 Div2 Problem 500 - PublicTransit (思维)
- Topcoder SRM 668 DIV 2
- TopCoder SRM 613 Div.2 C DFS+剪枝
- TopCoder SRM 140 Div2 第3题
- Topcoder SRM 652 DIV1 250
- topcoder srm 682 div1 -3
- Topcoder SRM 688 div2
- TopCoder SRM144 DIV1(one)
- TopCoder SRM Practice Room 144 DIV1