Description
因爲SJY乾的奇怪事情過多,SJY收到了休假的通知,於是他準備在都市間來回旅遊。SJY有一輛車子,一開始行駛性能爲0,每過1時間行駛性能就會提升1點。每個城市的道路都有性能要求。SJY一共有t時間休息,一開始他位於1號城市(保證1號城市道路要求爲0),他希望在n號城市結束旅程。每次穿過一條城市間的路會花費1時間,當然他也可以停留在一個城市不動而花費1時間。當且僅當車子的行駛性能大於等於一個城市,我們才能到達那裏。SJY希望知道,旅遊的方案模10086後的答案。(只要在某一時刻通過的道路存在一條不相同,就算不同的方案)
Input
第一行三個數n,m,t,表示有n個城市m條道路t時間。
第二行n個數,hi表示第i個城市的道路性能要求。
第三到m+2行,每行兩個數u,v,表示城市u與城市v之間有一條單向道路連接(可能有重邊)。
Output
包括一個數字,表示旅遊的方案模10086。
Sample Input
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
Sample Output
245
Data Constraint
對於20%的數據,n<=10,t<=80;
對於50%的數據,n<=30,t<=80;
對於100%的數據,n<=70,m<=1000,t<=100000000,hi<=70。
//written by zzy
題目大意:
給你個圖,有個城市,條邊,每個城市至少要第時間後才能經過,
走一條邊或呆在當前城市裏都會花費時間,
求在第時間時到第城市的方案數。
題解:
對於50%的數據,,可以考慮dp,
設表在第 時間到第 城市的方案數,表讀入時城市 到城市 的方案數
易推 //從在第 時間從城市 到城市
考慮滿分作法,
發現 ,即在第 時間後沒有限制,可以隨便走,
那麼每次矩陣 都會乘上矩陣 ,
( ,即枚舉 ,從 到 再走到 的方案數,
也即走兩個時間從 到 的方案數
那麼 即走 個時間從 到 的方案數)
用dp處理前 時間和用矩陣快速冪後 的時間
因爲矩陣乘法有結合律
再令 與 ·at-70 相乘,
答案爲
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 75
#define T 85
#define Mod 10086
using namespace std;
int i,j,k,n,l,t,x,y;
int h[N],f[T][N];
struct Mal{
long long m[N][N];
};
Mal a,b,ans;
Mal mult(Mal x,Mal y) {
Mal re;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
re.m[i][j]=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
re.m[i][j]=(re.m[i][j]+(x.m[i][k]*y.m[k][j])%Mod)%Mod;
return re;
}
void mal_ksm(long long p) {
for (int i=1;i<=n;i++)
ans.m[i][i]=1;
while (p) {
if (p&1) ans=mult(ans,a);
p>>=1;
a=mult(a,a);
}
}
int main()
{
scanf("%d%d%d",&n,&l,&t);
for (i=1;i<=n;i++)
scanf("%d",&h[i]);
for (i=1;i<=l;i++) {
scanf("%d%d",&x,&y);
a.m[x][y]++;
}
f[0][1]=1;
for (i=1;i<=n;i++) a.m[i][i]=1;
for (i=1;i<=min(t,70);i++)
for (j=1;j<=n;j++)
if (h[j]<=i)
for (k=1;k<=n;k++)
f[i][j]=(f[i][j]+(f[i-1][k]*a.m[k][j])%Mod)%Mod;
if (t<=70) {
printf("%d",f[t][n]); return 0;
}
mal_ksm(t-70);
a=ans;
for (j=1;j<=n;j++)
for (k=1;k<=n;k++)
f[71][j]=(f[71][j]+(f[70][k]*a.m[k][j])%Mod)%Mod;
printf("%d",f[71][n]);
}