hdu 5807 分步dp

有三个人分别在三个位置,每一秒各走一步,三个城市可以联络的要求是两两权值差小于等于K。问有多少种不同的方案,让这三个人可以联络。

dp[x][y][z]表示三个人分别在x,y,z时的答案,直接转移要花n^6,考虑每个人走一步是一种状态,即再加一维表示即将要走的人是哪一个,按照顺序转移0,1,2,0,1,2......所以就能转移。在dp[i][j][k][0]的时候三位步长一样。此时为答案,而如果这一个点是0说明这个状态本身就不能到,所以直接就是0,不可转移。

#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <cstdlib>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
#define mod 998244353
using namespace std;
typedef long long LL;
int w[55];
LL dp[55][55][55][4];
vector<int>vec[55];
int check(int i,int j,int k,int K)
{
    if (abs(w[i]-w[j])>K) return 0;
    if (abs(w[j]-w[k])>K) return 0;
    if (abs(w[i]-w[k])>K) return 0;
    return 1;
}
int main()
{
    int T;
    scanf ("%d",&T);
    while (T--)
    {
        for (int i=1;i<=50;i++) vec[i].clear();
        memset(dp,0,sizeof(dp));
        int n,m,K,q;
        scanf ("%d%d%d%d",&n,&m,&K,&q);
        for (int i=1;i<=n;i++)
        {
            scanf ("%d",&w[i]);
        }
        for (int i=1;i<=m;i++)
        {
            int u,v;
            scanf ("%d%d",&u,&v);
            vec[u].push_back(v);
        }
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++)
            {
                for (int k=1;k<=n;k++)
                {
                    if (check(i,j,k,K)) dp[i][j][k][0]=1;
                    else dp[i][j][k][0]=0;
                }
            }
        }
        for (int i=n;i>=1;i--)
        {
            for (int j=n;j>=1;j--)
            {
                for (int k=n;k>=1;k--)
                {
                    int sz=vec[k].size();
                    for (int tt=0;tt<sz;tt++)
                    {
                        int to=vec[k][tt];
                        dp[i][j][k][2]+=dp[i][j][to][0];
                        dp[i][j][k][2]%=mod;
                    }
                    sz=vec[j].size();
                    for (int tt=0;tt<sz;tt++)
                    {
                        int to=vec[j][tt];
                        dp[i][j][k][1]+=dp[i][to][k][2];
                        dp[i][j][k][1]%=mod;
                    }
                    if (dp[i][j][k][0]==0) continue;
                    sz=vec[i].size();
                    for (int tt=0;tt<sz;tt++)
                    {
                        int to=vec[i][tt];
                        dp[i][j][k][0]+=dp[to][j][k][1];
                        dp[i][j][k][0]%=mod;
                    }
                }
            }
        }
        while (q--)
        {
            int t1,t2,t3;
            scanf ("%d%d%d",&t1,&t2,&t3);
            printf ("%lld\n",dp[t1][t2][t3][0]);
        }
    }
    return 0;
}
时间: 2024-08-10 23:27:50

hdu 5807 分步dp的相关文章

hdu 4734 数位dp

http://acm.hdu.edu.cn/showproblem.php?pid=4734 Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, plea

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853 题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望: 回头再推次,思想跟以前的做过的类似 注意点:分母为0的处理 #include <cstdio> #include <cstring> #include <algorithm>

HDU 4968 (水dp 其他?)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <map> 6 using namespace std; 7 const int inf = 0x3f3f3f3f; 8 const int MAX = 200+10; 9 double GPA[10],dp1[20][30000],dp2[20][30000

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

HDU 3853 概率dp

LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 2337    Accepted Submission(s): 951 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl).Homura wants to help he

hdu 1087 简单dp

思路和2391一样的.. <span style="font-size:24px;">#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int inf=(0x7f7f7f7f); int main() { int a; int s[10005]; int w[10005];

HDU 2845 Beans(DP,最大不连续和)

题意    吃豆子游戏    当你吃了一个格子的豆子   该格子左右两个和上下两行就不能吃了    输入每个格子的豆子数    求你最多能吃多少颗豆子 可以先求出每行你最多可以吃多少颗豆子   然后每行就压缩成只有一个格子了   里面的豆子数就是那一行最多可以吃的豆子数   然后问题就变成求一列最多可以吃多少颗豆子了   和处理每一行一样处理   那么问题就简化成求一行数字的最大不连续和问题了 令d[i]表示某一行前i个豆子的最大和  有两种情况  吃第i个格子中的豆子和不吃第i个格子中的豆子

hdu 1250 树形DP

Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-27) Description There is going to be a party to celebrate the 80-th Anniversary of the Ural St

hdu 4352 数位dp(最长上升子序列的长度为k的个数)

http://acm.hdu.edu.cn/showproblem.php?pid=4352 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the entire description is very important. As the strongest fighting force in UESTC, xhxj grew