题解:AT_abc244_e [ABC244E] King Bombee

一道图上 DP 的好题。

(题目自己看,我就不说了。)

首先一看到求方案数,首先就要反应的是 DP 或者排列组合,反正考试的时候我写半天排列组合没写出来,所以就只能是 DP 了。(好牵强的理由啊……)

既然是 DP,那我们看看 DP 表示什么。自然是求啥设啥,那应该开几维呢?怎么写状态转移方程呢?

首先我们来解决第一个问题:我们看看题目中有几个不定量。不难发现,最主要的一共有三个:当前所在的点、总长度和经过 XXX 的次数。所以 DP 一共就有三维。(正好开下数据范围。)

接着我们来写状态转移方程,其实我们把 DP 设出来之后就很好写状态转移方程了,具体如下:

{dpi,j,0=dpi,j,0+dpi−1,to,0,dpi,j,1=dpi,j,1+dpi−1,to,1j≠tdpi,j,0=dpi,j,0+dpi−1,to,1,dpi,j,1=dpi,j,1+dpi−1,to,0j=t\begin{cases} dp_{i,j,0}=dp_{i,j,0}+dp_{i-1,to,0},dp_{i,j,1}=dp_{i,j,1}+dp_{i-1,to,1}&j\not=t\\dp_{i,j,0}=dp_{i,j,0}+dp_{i-1,to,1},dp_{i,j,1}=dp_{i,j,1}+dp_{i-1,to,0}&j=t\end{cases}{dpi,j,0=dpi,j,0+dpi1,to,0,dpi,j,1=dpi,j,1+dpi1,to,1dpi,j,0=dpi,j,0+dpi1,to,1,dpi,j,1=dpi,j,1+dpi1,to,0j=tj=t

其中 tototo 表示从 jjj 能到的点。

AC 代码:

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int n,m,k,s,t,x,dp[2006][2006][2];
vector<int>v[2006];
signed main()
{
    cin>>n>>m>>k>>s>>t>>x;
    for(int i=1,y,z;i<=m;i++)
    {
        cin>>y>>z;
        v[y].emplace_back(z);
        v[z].emplace_back(y);
    }
    dp[0][s][0]=1;
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(auto l:v[j])
            {
                if(j==x)
                {
                    dp[i][j][0]+=dp[i-1][l][1],dp[i][j][0]%=mod;
                    dp[i][j][1]+=dp[i-1][l][0],dp[i][j][1]%=mod;
                }
                else
                {
                    dp[i][j][0]+=dp[i-1][l][0],dp[i][j][0]%=mod;
                    dp[i][j][1]+=dp[i-1][l][1],dp[i][j][1]%=mod;
                }
            }
        }
    }
    cout<<dp[k][t][0]%mod;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值