codeforces869C The Intriguing Obsession 动态规划

题目链接:戳这里

题目大意:

齐心协力,我们可以以超乎想象的速度到达任何地方!现在,火炎姐妹(Fire Sisters)——火怜(Karen)和月火(Tsukihi)正在前往一个她们从未到达的地方——水中的小岛!

有三种不同类型的小岛,方便地,各自涂上了红,蓝,紫三色。每种颜色的小岛各自有a,b,c个。

这些小岛之间初始时互相分离。可以在小岛之间架桥,两个小岛间最多架一座桥。

但要满足:任意两个不同的颜色相同的小岛的最短距离要大于等于3(桥的长度为1)。

火炎姐妹已经准备好迎接未知了,但是她们想测试一下你的勇气。你需要计算出不同的架桥方案有多少种,如果有两个小岛之间造桥的方案变了,我们就说这两个造桥的方案不同。答案对998244353取模。

题解:题目很绕,转换一下就是相同颜色的岛不能直接连边。

那么我们用dp[i][j]表示i个a颜色与j个b颜色的岛的连边方案数,答案就是dp[a][b]*dp[b][c]*dp[a][c]。

转移的话,要么不连边,要么就有j种连边方式,所以dp[i][j]=dp[i-1][j]+dp[i-1][j-1]*j。

代码:

#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long LL;
int read()
{
    char c;int sum=0,f=1;c=getchar();
    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
    return sum*f;
}
int a,b,c;
LL dp[5005][5005];
int main()
{
    a=read();b=read();c=read();
    int lim=max(max(a,b),c);
    for(int i=0;i<=lim;i++) dp[i][0]=dp[0][i]=1;
    for(int i=1;i<=lim;i++)
    for(int j=1;j<=lim;j++)
    dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]*j%mod)%mod;
    printf("%lld\n",dp[a][b]*dp[a][c]%mod*dp[b][c]%mod);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39791208/article/details/79384447