3 3 3 3 3 3 3 3 1 1
一个无向图,有三个人,起点任意,但是三个人所在城市的频率差值不大于k 每次三人都必须移动到下一个点或者三人选择此时结束任务
问 对于起始点i j k 有几种结束方案
记忆化搜索 暴力枚举起点状态
/************************************************
┆ ┏┓ ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃ ┃ ┆
┆┃ ━ ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃ ┃ ┆
┆┃ ┻ ┃ ┆
┆┗━┓ ┏━┛ ┆
┆ ┃ ┃ ┆
┆ ┃ ┗━━━┓ ┆
┆ ┃ AC代马 ┣┓┆
┆ ┃ ┏┛┆
┆ ┗┓┓┏━┳┓┏┛ ┆
┆ ┃┫┫ ┃┫┫ ┆
┆ ┗┻┛ ┗┻┛ ┆
************************************************ */
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#define ll long long
using namespace std;
ll sum[55][55][55];
int n,m,K,q;
bool Map[55][55];
int num[55],d[55];
const ll mod=998244353;
bool cheak(int i,int j,int l)
{
if(num[i]-num[j]>K||num[j]-num[i]>K) return false ;
if(num[i]-num[l]>K||num[l]-num[i]>K) return false ;
if(num[l]-num[j]>K||num[j]-num[l]>K) return false ;
return true ;
}
int Abs(int i)
{
if(i<0) i=-i;
return i;
}
ll dfs(int i,int j,int k)
{
if(sum[i][j][k]>=0) return sum[i][j][k];
ll ans=0;
for(int ii=1; ii<=n; ii++)
{
if(Map[i][ii])
{
for(int jj=1; jj<=n; jj++)
{
if(Map[j][jj]&&Abs(num[ii]-num[jj])<=K)
{
for(int l=1; l<=n; l++)
{
if(Map[k][l]&&cheak(ii,jj,l))
{
ans=(ans+dfs(ii,jj,l))%mod;
}
}
}
}
}
}
sum[i][j][k]=(ans+1)%mod;
return (ans+1)%mod;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&n,&m,&K,&q);
for(int i=1; i<=n; i++) scanf("%d",&num[i]);
memset(sum,-1,sizeof(sum));
memset(Map,false ,sizeof(Map));
memset(d,0,sizeof(d));
for(int i=0; i<m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
Map[u][v]=true;
d[v]++;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(Abs(num[i]-num[j])<=K)
for(int k=1; k<=n; k++)
if(cheak(i,j,k))
sum[i][j][k]=dfs(i,j,k);
for(int i=0; i<q; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%d\n",sum[a][b][c]);
}
}
return 0;
}
原文:http://blog.csdn.net/u013097262/article/details/52138463