AtCoder Beginner Contest 244 E - King Bombee(动态规划)
原题连接:https://atcoder.jp/contests/abc244/tasks/abc244_e
官方题解:https://atcoder.jp/contests/abc244/editorial/3619
题意
简单无向图,n个点,m条边。从S到T经过K条边,X出现的数量是偶数,一共有多少种方案
思路
- 
先不考虑x出现的数量为偶数这个条件,用动态规划 
 状态表示:f[i][j]表示从S到j经过i条边的所有方案的数量
 状态划分:f[i + 1][j] += f[i][k], k是所有j能到的点
 初始化:f[0][S] = 1
 答案:f[K][T]
- 
考虑x为偶数这个条件,多了一个限制,状态就要多一维 
 状态表示:f[i][j][x]表示从S到j经过i条边,并且经过X的次数模2的余数为x的所有方案的数量
 状态划分:1. 当j不为X时,f[i + 1][j][x] += f[i][k][x], k是所有j能到的点2. 当j为X时,f[i + 1][j][x] += f[i][k][(x+1)%2]
 初始化:f[0][S][0] = 1
 答案:f[K][T][0]
代码
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 2010, M = N * 2;
LL mod = 998244353;
int h[N], e[M], ne[M], idx;
LL f[N][N][2];
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int main()
{
    int n, m, k, S, T, X;
    cin >> n >> m >> k >> S >> T >> X;
    memset(h, -1, sizeof h);
    
    while (m -- )
    {
        int u, v;
        cin >> u >> v;
        add(u, v);
        add(v, u);
    }
    
    f[0][S][0] = 1;
    for(int i = 0; i <= k; i ++ )
        for(int j = 1; j <= n; j ++ )
            for(int x = 0; x < 2; x ++ )
            {
                for(int u = h[j]; ~u; u = ne[u])
                {
                    int k = e[u];
                    if(j != X)  f[i + 1][j][x] = ((LL)f[i + 1][j][x] + f[i][k][x]) % mod;
                    else    f[i + 1][j][x] = ((LL)f[i + 1][j][x] + f[i][k][(x + 1) % 2]) % mod;
                }
            }
    cout << f[k][T][0];
    return 0;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号