時間限制: 1 s
空間限制: 256000 kb
題目等級 : 鑽石 diamond
題解
檢視執行結果
n個節點的有向圖, 求從start到finish剛好經過時間time的總方案數 mod 502630.
輸入描述 input description
第一行包含乙個整數n, 所有點是從0到n-1編號.
接下來n行,每行包含n個字元. 第i行第j個字元表示i到j需要的時間. 字元只可能是』1』到』5』, 或者是』.』表示i不能到達j. 保證主對角線都是』.』.
接下來一行3個整數start, finish, time.
輸出描述 output description
輸出總方案數.
樣例輸入 sample input
3.12
2.112.
0 2 5
樣例輸出 sample output
8 資料範圍及提示 data size & hint
對於20%的資料, 輸入的字元不是』1』就是』.』;
對於100%的資料, 1 <= n <= 10; 1 <= start,finish <= n; 1 <= time <= 10^9.
分類標籤 tags 點此展開
很容易想到dp.
定義dp[i][j][k]表示從i到j用時間為k的方案數,dp[i][j][k]=∑dp[i][p][k-cost[p][j]]*dp[p][j][cost[p][j]],轉移是o(n)的,列舉3個變數,加起來大致是n^3*time的時間複雜度,很明顯是不能接受的。
如果等式右邊的第3維是1的話,左邊k=2,這樣不考慮第三維,這種轉移是不是很眼熟,沒錯,就是矩陣的轉移。
當所有花費為1的時候,我們直接用矩陣快速冪一下就好了,快速冪k次用的時間就為k.
題意中花費不一定為1啊?- -
但是最大也才5,我們想象把乙個點"。"拆成"。->。->。->。->。" 每條邊權值為1,如果權值為3,就把第3個點和j相連為1,這樣就構成了時間全為1的01矩陣,然後快速冪跑一次就好了。
開始寫掛了,發現資料死活不對,把資料開成long long發現就對了,奇葩- -
附上大神都懶得發的碼:
#include#include#include#include#include#include#include#define ll long long
using namespace std;
const ll m=502630;
const ll maxn=65;
/*定義dp[i][j][k]為從i到j經過k秒的方案數
dp[i][j][k]=∑dp[i][p][i~p]*dp[p][j][p~j]
如果等式右邊的第三維經過的都是1s,經過兩秒就是等式左邊。
考慮拆點構造乙個矩形,將其自乘n次(i,j)就是答案
*/ll n;
struct mat
};mat operator*(mat a,mat b)
} }return c;
}mat operator^(mat a,ll k)
return c;
}char ss[65];
ll tot;
int main()
} for(ll i=1;i<=n;i++)
}} ll st,ft,k;
scanf("%lld%lld%lld",&st,&ft,&k);
st++;
ft++;
g=f^k;
printf("%lld\n",g.mat[st][ft]);
return 0;
}
148 合併果子
一道huffman樹問題,貪心在每一次合併堆的時候,都取最小的兩個堆合併。用乙個優先佇列 小頂堆 來存下所有堆的資料,每次取前面兩個合併就可以了。acwing282.石子合併 設有n堆石子排成一排,其編號為1,2,3,n。每堆石子有一定的質量,可以用乙個整數來描述,現在要將這n堆石子合併成為一堆。每...
1 4 8 表空間維護
背景資訊 oracle表空間利用率超過80 時,需要擴充套件表空間來保證lbi正常執行。查詢表空間利用率 步驟1 以oracle使用者登入作業系統。步驟2 登入資料庫 sqlplus as sysdba 步驟3 查詢表空間利用率 sql select a.tablespace name,a.used...
148 鍊錶排序
每趟將乙個待排序的關鍵字按照其值的大小將其插入到已經排好的部分有序序列的適當位置上,直到所有待排關鍵字都被插入到有序序列中為止。public void select sort int nums nums j 1 temp 找到插入位置,將temp中暫存的待排關鍵字插入 鍊錶的直接插入排序 如果是陣列...