矩陣類 poj3420
第一次寫部落格,希望以後能有個美好的回憶。。
決心把 演算法與實現的題 都做一遍,加油!
這題我這個菜鳥整整研究了一個晚上才弄明白。。。好弱啊。。
已知第i行的狀態,推匯出第i+1行的可行性狀態,狀態用0,1,表示,同一行2個0表示一個橫著的骨牌,同一列1個1表示豎著的骨牌
比如 第i行為 0000,(用數字1,2,3,4表示骨牌)
那麼第i+1行的狀態可以為 0000 即
1122
3344
也可以為0011,即
1134
2234
也可以為1111,即
1234
1234
。
。
。
用陣列t[i][j]表示i和j是否是可行性狀態,比如
i行: 0100
i+1行: 1011
那麼t[4][11]=1
這樣計算出狀態方程t
計算方法為 保證i和j二進位制的每一位最多有一個1,並且i^j=0000||0011||1001||1100||1111
計算完t後,利用矩陣快速冪計算a=t^n,最後a[0][0]就是答案
至於為什麼a[0][0]是答案,我感覺a[i][j]表示的以i為第一行j為最後一行的所有可能情況
當n=1是不用說了
當n=2是所有的情況都可以寫成以0000為第一行的形式即
0000 0000 0000 0000 0000
0000 0011 1001 1100 1111
即1122 1134 1224 1233 1234
3344 2234 1334 1244 1234
五種情況
當n=3時
可以都可以寫成
0000 0000 0000 0000 0000
0000 0011 1001 1100 1111
0000 0000 0000 0000 0000
即11種情況
所以以後無論n為奇數偶數都可由n=2和n=3的情況組合而成
而a[0][0]表示以0000開頭 以0000結尾的情況 符合要求
所以a[0][0]就是答案
決心把 演算法與實現的題 都做一遍,加油!
這題我這個菜鳥整整研究了一個晚上才弄明白。。。好弱啊。。
已知第i行的狀態,推匯出第i+1行的可行性狀態,狀態用0,1,表示,同一行2個0表示一個橫著的骨牌,同一列1個1表示豎著的骨牌
比如 第i行為 0000,(用數字1,2,3,4表示骨牌)
那麼第i+1行的狀態可以為 0000 即
1122
3344
也可以為0011,即
1134
2234
也可以為1111,即
1234
1234
。
。
。
用陣列t[i][j]表示i和j是否是可行性狀態,比如
i行: 0100
i+1行: 1011
那麼t[4][11]=1
這樣計算出狀態方程t
計算方法為 保證i和j二進位制的每一位最多有一個1,並且i^j=0000||0011||1001||1100||1111
計算完t後,利用矩陣快速冪計算a=t^n,最後a[0][0]就是答案
至於為什麼a[0][0]是答案,我感覺a[i][j]表示的以i為第一行j為最後一行的所有可能情況
當n=1是不用說了
當n=2是所有的情況都可以寫成以0000為第一行的形式即
0000 0000 0000 0000 0000
0000 0011 1001 1100 1111
即1122 1134 1224 1233 1234
3344 2234 1334 1244 1234
五種情況
當n=3時
可以都可以寫成
0000 0000 0000 0000 0000
0000 0011 1001 1100 1111
0000 0000 0000 0000 0000
即11種情況
所以以後無論n為奇數偶數都可由n=2和n=3的情況組合而成
而a[0][0]表示以0000開頭 以0000結尾的情況 符合要求
所以a[0][0]就是答案
不知道對不對,求大牛指點
# include <stdio.h>
# include <string.h>
const int maxn=16;
int t[maxn][maxn];
int a[maxn][maxn],b[maxn][maxn];
int dz[16];
int mod;
void mul(int d[maxn][maxn],int e[maxn][maxn],int f[maxn][maxn])
{
int temp[maxn][maxn];
for(int i=0; i<maxn; i++)
{
for(int j=0; j<maxn; j++)
{
temp[i][j]=0;
for(int k=0; k<maxn; k++)
{
temp[i][j]=(temp[i][j]+d[i][k]*e[k][j])%mod;
}
}
}
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
f[i][j]=temp[i][j];
}
void pow(int n)
{
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
a[i][j]=t[i][j];
memset(b,0,sizeof(b));
for(int i=0; i<maxn; i++)
b[i][i]=1;
while(n)
{
if(n&1) mul(b,a,b);
mul(a,a,a);
n>>=1;
}
}
void init()
{
dz[0]=dz[3]=dz[9]=dz[12]=dz[15]=1;
for(int i=0; i<16; i++)
{
for(int j=0; j<16; j++)
{
int k;
for(k=0; k<4; k++){
if((i&(1<<k))&&(j&(1<<k))) break;
}
if(k==4&&dz[i^j]==1) t[i][j]=1;
}
}
}
int main ()
{
init();
int n;
while(scanf("%d%d",&n,&mod)!=EOF)
{
if(n==0&&mod==0) break;
pow(n);
//for(int i=0; i<16; i++){for(int j=0; j<16; j++) printf("%d ",b[i][j]); printf("\n");}
printf("%d\n",b[0][0]);
}
}
相關文章
- 生成螺旋矩陣(方陣、矩陣)矩陣
- 鄰接矩陣、度矩陣矩陣
- 巨大的矩陣(矩陣加速)矩陣
- (原創)一般矩陣 Matrix類矩陣
- 奇異矩陣,非奇異矩陣,偽逆矩陣矩陣
- 用三列二維陣列表示的稀疏矩陣類陣列矩陣
- 矩陣矩陣
- 資料結構:陣列,稀疏矩陣,矩陣的壓縮。應用:矩陣的轉置,矩陣相乘資料結構陣列矩陣
- 3D圖形:矩陣的行列式,矩陣的逆、正交矩陣、齊次矩陣3D矩陣
- 矩陣中最大的二維矩陣矩陣
- 求任意矩陣的伴隨矩陣矩陣
- 機器學習中的矩陣向量求導(五) 矩陣對矩陣的求導機器學習矩陣求導
- 矩陣和陣列矩陣陣列
- Flutter 45: 圖解矩陣變換 Transform 類 (二)Flutter圖解矩陣ORM
- 理解矩陣矩陣
- 矩陣相乘矩陣
- 矩陣分解矩陣
- 稀疏矩陣矩陣
- Numpy 矩陣矩陣
- 穿越矩陣矩陣
- 混淆矩陣矩陣
- 魔方矩陣矩陣
- 海浪矩陣矩陣
- 8.6 矩陣?矩陣
- 螺旋矩陣矩陣
- 找矩陣矩陣
- 矩陣乘法矩陣
- 快手矩陣管理平臺,矩陣管理有方法矩陣
- Wannafly模擬賽 矩陣 二維矩陣hash矩陣
- 矩陣:如何使用矩陣操作進行 PageRank 計算?矩陣
- 演算法學習:矩陣快速冪/矩陣加速演算法矩陣
- 視訊矩陣矩陣
- 高斯消除矩陣矩陣
- 矩陣轉置矩陣
- 矩陣樹定理矩陣
- 矩陣消除遊戲矩陣遊戲
- 08:矩陣加法矩陣
- 旋轉矩陣矩陣