Title Link: BZOJ-2165
Topic Analysis:
This problem I read the question after I can not think of how to do, the problem can not find, so asked the Huang long, Huang immediately seconds dropped the problem, and then I look at his problems to write out. Orz
Using DP + multiplier, using the state F[x][i][j] means starting from I, take x times elevator to reach J, up to the number of layers that can rise. The f[1][][] array to begin reading in. (Note: If I cannot walk to J at the beginning, then f[1][i][j] =-inf)
Use multiplication, use f[x][][] to find F[x << 1][][], always ask for f[2^p][][], until the first row of the array of f[][][] that is found has a value greater than or equal to M.
F[a][][] and f[b][][] to find the state transition equation of f[a+b][][] is similar to Floyd: f[a+b][i][j] = max (F[a][i][k] + f[b][k][j])
Then enumerate each bits, piecing together the answers. If you cannot reach m after joining this bits, join this one. The final answer will be 1. (Similar multiplication for LCA)
The code is as follows:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm>using namespace std;const int maxn = + 5;typedef long long ll;const LL INF = 1e18;int T, N, Top; ll m, ans;struct Matrix {ll num[maxn][maxn];void Clear (ll x) {for (int i = 1; I <= n; ++i) {for (int j = 1; j <= N; ++J) {Num[i][j] = x;}}}} M[70 + 5], M0, Temp; ll Gmax (ll A, ll b) {return a > b a:b;} Matrix Mul (Matrix A, Matrix B) {matrix Ret;ret. Clear (-inf), for (int k = 1, k <= N; ++k) {for (int i = 1; I <= n; ++i) {for (int j = 1; j <= N; ++j) {ret. NUM[I][J] = Gmax (ret. NUM[I][J], A.num[i][k] + b.num[k][j]); if (ret. NUM[I][J] > m) ret. Num[i][j] = m;}}} return ret;} BOOL Check (Matrix A) {for (int i = 1; I <= n; ++i) if (A.num[1][i] >= m) return True;return false; int main () {scanf ("%d", &t); for (int case = 1; Case <= T; ++case) {scanf ("%d%lld", &n, &m); for (int i = 1; I <= n; ++i) {for (int j = 1; J <= N; ++J) {scanf ("%lld", &m[0]. NUM[I][J]); if (m[0]. NUM[I][J] = = 0LL) m[0]. NUM[I][J] =-inf;}} Top = 0;while (true) {++top; M[top] = Mul (M[top-1], m[top-1]), if (Check (M[top])) break; Ans = 0LL; M0. Clear (0); for (int i = Top; I >= 0; i) {Temp = Mul (M[i], M0); Check (temp)) {M0 = temp; Ans + = (1ll << i);}} printf ("%lld\n", Ans + 1);} return 0;}
[Bzoj 2165] Building "DP + multiply + binary"