都市环游

来源:互联网 发布:英国圣玛丽大学知乎 编辑:程序博客网 时间:2024/04/27 20:04

题目描述
因为SJY干的奇怪事情过多,SJY收到了休假的通知,于是他准备在都市间来回旅游。SJY有一辆车子,一开始行驶性能为0,每过1时间行驶性能就会提升1点。每个城市的道路都有性能要求。SJY一共有t时间休息,一开始他位于1号城市(保证1号城市道路要求为0),他希望在n号城市结束旅程。每次穿过一条城市间的路会花费1时间,当然他也可以停留在一个城市不动而花费1时间。当且仅当车子的行驶性能大于等于一个城市,我们才能到达那里。SJY希望知道,旅游的方案模10086后的答案。(只要在某一时刻通过的道路存在一条不相同,就算不同的方案)
输入
第一行三个数n,m,t,表示有n个城市m条道路t时间。
第二行n个数,hi表示第i个城市的道路性能要求。
第三到m+2行,每行两个数u,v,表示城市u与城市v之间有一条单向道路连接(可能有重边)。
输出
包括一个数字,表示旅游的方案模10086。
样例输入
5 17 7
0 2 4 5 3
1 2
2 1
1 3
3 1
1 4
4 1
4 5
5 4
5 3
4 1
2 1
5 3
2 1
2 1
1 2
2 1
1 3
样例输出
245
提示
【数据规模和约定】
对于20%的数据,n<=10,t<=80;
对于50%的数据,n<=30,t<=80;
对于100%的数据,n<=70,m<=1000,t<=100000000,hi<=70。

对于50%的数据,很容易想到dp转移方程,记dp[i,j]表示i时刻到j点的方案总数,dp[i,j]=dp[i-1,k]*a[k,j]; a[k,j]为k到j的路经数。

对于100%的数据,我们发现hi<=70,也就是说70s以后我们就可以随便走了,于是我们想到了矩阵乘法,70s以后直接用矩阵算,70s之前用dp算。

type al=array[0..80,0..80] of longint;varn,m,t,i,x,y,j,k:longint;a,dp,f,ans:al;h:array[0..1000] of longint;function chen(x,y:al):al;vari,j,k:longint;begin  for i:=1 to n do    for j:=1 to n do    begin      chen[i,j]:=0;      for k:=1 to n do        chen[i,j]:=(chen[i,j]+x[i,k]*y[k,j]) mod 10086;    end;end;function gpow(k:longint):al;vart:al;begin  if k=1 then exit(a);  t:=gpow(k div 2);  t:=chen(t,t);  if k mod 2=1 then t:=chen(t,a);  exit(t);end;begin  readln(n,m,t);  for i:=1 to n do    read(h[i]);  readln;  for i:=1 to m do  begin    readln(x,y);    a[x,y]:=a[x,y]+1;  end;  for i:=1 to n do    a[i,i]:=a[i,i]+1;  dp[0,1]:=1;  for i:=1 to 70 do    for j:=1 to n do      for k:=1 to n do       if (i>=h[k])and(a[j,k]>0) then dp[i,k]:=(dp[i,k]+dp[i-1,j]*a[j,k]) mod 10086;  if t<=70 then write(dp[t,n])  else  begin    ans:=gpow(t-70);    for i:=1 to n do      for k:=1 to n do        dp[71,k]:=(dp[71,k]+dp[70,i]*ans[i,k]) mod 10086;    write(dp[71,n]);  end;end.
0 0
原创粉丝点击