題意:現有乙個n行m列的棋盤,乙隻馬欲從棋盤的左上角跳到右下角。每一步它向右跳奇數列,且跳到本行或相鄰行。試求跳法種數mod 30011。
題解:dp+矩陣乘法+快速冪 設f
[i][
j]表示走到第2i
−1列,第
j 行的方案數,g[
i][j
]表示走到第2i
列,第j行的方案數。那麼f[
i][j
]=∑k
=1i−
1g[k
][j−
1]+∑
k=1i
−1g[
k][j
]+∑k
=1i−
1g[k
][j+
1]g[
i][j
]=∑k
=1if
[k][
j−1]
+∑k=
1if[
k][j
]+∑k
=1if
[k][
j+1]
設f[i][j
]=∑i
k=1f
[k][
j],g
[i][
j]=∑
ik=1
g[k]
[j] 那麼f[
i][j
]=f[
i−1]
[j]+
g[i−
1][j
−1]+
g[i−
1][j
]+g[
i−1]
[j+1
]g[i
][j]
=g[i
−1][
j]+f
[i][
j−1]
+f[i
][j]
+f[i
][j+
1]矩陣推一推就出來了。
**:
#include
using
namespace
std;
struct matrix
int* operator(int x)
}a,b,one;
int mod=30011,n,m;
matrix operator*(matrix x,matrix y)
matrix pow(matrix x,int y)
int main()
for(int i=1;i<=n;i++)
/*for(int i=1;i<=(n<<1);i++)
puts("");
for(int i=1;i<=(n<<1);i++)
*/for(int i=1;i<=(n<<1);i++)
one[i][i]=1;
one.x=one.y=n<<1;
a=a*b;
int hh=m+1>>1;
matrix ans;
ans.x=1;
ans.y=n<<1;
ans[1][1]=ans[1][n+1]=ans[1][n+2]=1;
if(hh<2)
else
return
0; }
matrix c=pow(a,hh-2);
ans=ans*c;
matrix oo=ans*a;/*
for(int i=1;i<=(n<<1);i++)
printf("%d ",oo[1][i]);
puts("");
for(int i=1;i<=(n<<1);i++)
printf("%d ",ans[1][i]);
puts("");*/
if(m&1)
printf("%d",(oo[1][n]-ans[1][n]+mod)%mod);
else
printf("%d",(oo[1][n<<1]-ans[1][n<<1]+mod)%mod);
}
Bzoj3562 神器化合物 Shoi 2014
ac通道 分析 若把每乙個原子看作乙個節點,將化學鍵看作一條邊,那麼這個題目要求的 分子的個數 很容易就可以看出是求圖中聯通塊的個數。求聯通塊的個數,可以使用並查集。可如何求出每一步的聯通塊的個數呢?可以知道,當連上一條邊時,若此邊連線的是兩個不同的聯通塊,那麼分子個數就會減一 當刪去一條邊時,若刪...
BZOJ 3566 SHOI2014 概率充電器
題目 題意 給定樹形結構的n個元件,每個元件有一定概率自己充電,還有一定概率通過某條邊給其他元件充電,求充電的元件期望個數。n 500000 題解 樹形結構肯定能想到樹形dp,全樹對某點產生的貢獻一般可以通過一到兩遍樹形dp計算得出,本題所求期望等於每個元件被充電的概率之和。設f i 表示i被充電的...
bzoj3566 SHOI2014 概率充電器
n個充電器連成一棵樹。第i個充電器有p i 的概率直接充電。每條導線有一定機率可以導電。可以導電的導線形成的聯通塊中只要存在直接充電的結點整個聯通塊的充電器均進入充電狀態。問期望進入充電狀態的充電器個數 顯然可知我們只需要得到f i 表示i進入充電狀態的概率 那麼a ns f i 我們把無根樹變有根...