【题意】从第0层开始有无穷层,每层有n个房间,给定矩阵A,A[i][j]表示从第x层的房间 i 可以跳到第x+A[i][j]层的房间 j (x任意),A[i][j]=0表示不能跳。初始在第0层第1个房间,求最少跳几次可以到达>=m层。n<=100,m<=10^18。

【算法】矩阵快速幂

【题解】我的写法好像和网上的不太一样……

设$f_n[i]$表示跳n步在房间 i 的最高层数(这里全部的n和题目的n无关),考虑递推列向量$f_n$,设转移矩阵T,满足$T_{i,j}=A_{j,i}$,那么有:

$$T \times f_n=f_{n+1}$$

初始状态f0={1,0,0...0},那么写成幂形式:

$$T^n \times f_0=f_n$$

为了方便,容易发现$T^n$的最左一列就是$f_n$。

我们要跳到$f_n$中包含>=m的数字为止,所以预处理所有$T^{2^i}$,倍增即可。

复杂度O(n^3*log m+n log m)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=;
const ll inf=;
ll m,c2[N],c[N][N],A[][N][N],ans[N][N],ans2[N][N];
int n;
void multply(ll a[N][N],ll b[N][N],ll d[N][N]){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
c[i][j]=-inf;//
for(int k=;k<=n;k++){
c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
}
}
}
for(int i=;i<=n;i++)for(int j=;j<=n;j++)d[i][j]=c[i][j];
}
int main(){
int T;scanf("%d",&T);
while(T--){
scanf("%d%lld",&n,&m);
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
scanf("%lld",&A[][j][i]);
if(A[][j][i]==)A[][j][i]=-inf;
}
}
int tot=;
bool ok=;
for(int i=;i<=n;i++)if(A[tot][i][]>=m){ok=;break;}
if(!ok){
while(){
tot++;
multply(A[tot-],A[tot-],A[tot]);
bool ok=;
for(int i=;i<=n;i++)if(A[tot][i][]>=m){ok=;break;}
if(ok)break;
}
}
c2[]=;
for(int i=;i<=tot-;i++)c2[i]=c2[i-]*;
ll ANS=c2[tot-];
for(int i=;i<=n;i++)for(int j=;j<=n;j++)ans[i][j]=A[tot-][i][j];
for(int i=tot-;i>=;i--){
multply(ans,A[i],ans2);
bool ok=;
for(int j=;j<=n;j++)if(ans2[j][]>=m)ok=;
if(ok){
ANS+=c2[i];
for(int k=;k<=n;k++)for(int l=;l<=n;l++)ans[k][l]=ans2[k][l];//
}
}
printf("%lld\n",ANS+);
}
return ;
}

注意T[i][j]=0时设为-inf,即不可达。

网上的角度:关键在于题意的理解……给定n个点的有向图边权矩阵,0表示无边,求最少经过几条边使得路径长度>=m。

经过指定条边后的最长路矩阵是很容易知道的,设$C^x$表示经过x条边后的最长路矩阵,$A$表示有向边权矩阵(0要设为-inf),那么:

$$C^x(i,j)=\max_k\{C^{x-1}(i,k)+A(k,j)\}$$

所以C^x=A^x。

预处理$C^{2^i}$,然后倍增到第一行出现>=m的数字为止。

复杂度O(n^3 log m+n log m)。

【BZOJ】2165: 大楼的更多相关文章

  1. [BZOJ 2165] 大楼 【DP + 倍增 + 二进制】

    题目链接:BZOJ - 2165 题目分析: 这道题我读了题之后就想不出来怎么做,题解也找不到,于是就请教了黄学长,黄学长立刻秒掉了这道题,然后我再看他的题解才写出来..Orz 使用 DP + 倍增 ...

  2. BZOJ 2165: 大楼 倍增Floyd

    卡了一上午常数,本地13s,可是bzoj 就是过不去~ #include <bits/stdc++.h> #define N 102 #define M 55 #define ll lon ...

  3. BZOJ 2165: 大楼

    Time Limit: 40 Sec Memory Limit: 259 MB Submit: 957 Solved: 353 [Submit][Status][Discuss] Descriptio ...

  4. bzoj 2165: 大楼【Floyd+矩阵乘法+倍增+贪心】

    1<<i的结果需要是long long的话i是long long是没用的--要写成1ll<<i--我别是个傻子吧 虽然写的是二进制贪心,但是我觉得二分可能更好写吧(但是会慢) ...

  5. 大楼(bzoj 2165)

    Description xz是一个旅游爱好者,这次他来到了一座新的城市.城市中央有一幢高耸入云的大楼.这幢楼到底有多少层呢?据说和非负整数的个数是一样多的.xz想爬上这座大楼来观赏新城市的全景.这幢大 ...

  6. bzoj 2165 DP

    首先如果不考虑数据范围的话,因为每一层都是等效的,所以我们可以用w[i][j][k]来表示在某一层的j位置,称作i次电梯到k位置,最多上升多少层,那么我们可以比较容易的写出转移,因为m十分大,i可能与 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. BZOJ刷题指南(转)

    基础(65) 巨水无比(4):1214.3816:2B题:1000A+B:2462:输出10个1 模拟/枚举/暴力(15):4063傻子模拟:1968小学生暴力:1218前缀和暴力:3856读英文:4 ...

  9. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

随机推荐

  1. StringBuilder、StringBuffer和String三者的联系和区别

    String 类    String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间.    String a = "a ...

  2. Hibernate:工作原理

    Hibernate的工作原理图如下所示:

  3. git找回当前目录下误删的所有文件

    git checkout . 参考:http://opentechschool.github.io/social-coding/extras/delete-restore.html

  4. java结合testng,利用XML做数据源的数据驱动示例

    testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以XML为例: 备注:@DataProvider的返回值 ...

  5. 【php】header下载文件后,文件变大的问题;(ob_clean()清空缓存)

    事由: 按照常理,为了下载一个生产的文件,都是使用header函数,指定下文件信息,然后开始下载,但是下载后发现,文件体积总是比源文件要大2个字节,源文件是24字节,下载后是26字节,查看服务器返回的 ...

  6. Linux架设DDNS服务器之自动更新脚本

    问题描述:客户端是动态IP,每次连网之后要nsupdate下才可以把客户端的hostname 与IP映射更新到DNS Server上 命令如下: nsupdate -k K*****.key > ...

  7. 题解 P1308 【统计单词数】

    小金羊发一篇不一样的题解: 这个题解不是讲解法的,是讲算法的... 众所周知,string在中被定义为是类型, 这意味着我们可以将它作为int一样的类型使用. 并且还有神奇的加减法: string s ...

  8. 题解 P1200 【[USACO1.1]你的飞碟在这儿Your Ride Is He…】

    cin其中有很多小众的函数与其他重叠 不妨拿来用用(作死不止) 划重点!!! 1.cin.get(),相当于c里面的getchar(),可以往里面输入字符 2.cin.getline(),相当于str ...

  9. C++解析(23):多态与C++对象模型

    0.目录 1.多态 2.C++对象模型 2.1 使用C语言实现封装 3.继承对象模型 4.多态对象模型 4.1 使用C语言实现多态 5.小结 1.多态 面向对象中期望的行为: 根据实际的对象类型判断如 ...

  10. day29:关闭服务|

    1. 在centos6系统里,我们可以使用ntsysv关闭不需要开机启动的服务,当然也可以使用chkconfig工具来实现. 写一个shell脚本,用chkconfig工具把不常用的服务关闭.脚本需要 ...