题意:给你n个点,将这些点放在一个环上,问你不相交的连k条线的方案数。(没有重点)
题解:dp[i][j]表示i个点连j条线的方案数,那么新加一个点i,情况1,i没有和之前的点相连,方案数为dp[i-1][j];
情况2,i和p号点相连(0<p<j),那么就划分成了两个环,然后枚举一些子问题的连边数,方案数为sum( dp[p-1][q]*dp[i-1-p]*dp[j-1-q] ) (0<=q<j)
#include<cstdio> #include<cmath> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long ll; //#define local const int maxn = 42; ll dp[maxn][maxn]; int main() { #ifdef local freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif // local int n,k; scanf("%d%d",&n,&k); for(int i = 0; i <= n; i++) dp[i][0] = 1; for(int i = 1; i <= n; i++ ){ for(int j = 0; j <=k; j++){ dp[i][j] = dp[i-1][j]; for(int p = 1; p < i; p++){ //枚举连到哪一个点 for(int q = 0; q < j; q++ ){ //枚举子问题的边数 dp[i][j] += dp[p-1][q]*dp[i-p-1][j-1-q]; } } } } printf("%I64d",dp[n][k]); return 0; }
时间: 2024-09-30 10:19:26