矩陣覆蓋那點事兒

2021-07-06 10:44:10 字數 3780 閱讀 9798

poj2663)用1 * 22 * 1的小矩形完全覆蓋3 * n的矩形有多少種方案。

顯然的,當n為奇數的時候無法完全覆蓋,即此時的答案是0;當n為偶數的時候,首先我們以2為乙個單位,每個3 * 2的矩形完全覆蓋共有3個方法,以4為乙個單位,每個3 * 4的矩形完全覆蓋共有2種方法,...依次類推。這樣得到方程:f[ i ] = 3 * f[ i - 2 ] + 2 * ( f[ i - 4 ] + f[ i - 6 ] + ... + f[ 0 ])。再進行簡化,根據剛才的式子,我們可以得出f[ i - 2 ] = 3 * f[ i - 4 ] + 2 * ( f[ i - 6 ] + ... + f[ 0 ]),所以2 * ( f[ i - 6 ] + f[ i - 8 ] + ... + f[ 0 ] ) = f[ i - 2 ] - 3 * f[ i - 4 ]。代回第乙個式子中:f[ i ] = 3 * f[ i - 2 ] + 2 * f[ i - 4 ] + f[ i - 2 ] - 3 * f[ i - 4 ] = 4 * f[ i - 2 ] - f[ i - 4 ]

特別地,f[ 0 ] = 1。我也不知道為什麼,但是當成 0 會 wa,可能是理解不一樣:① 0 的時候沒用小矩形可放,所以為 0 ;② 要滿足 0 的情況應該什麼都不放,所以唯一的乙個答案就是什麼都不放,所以為 1 (自己胡說)。

#include using namespace std;

const int max_n = 35;

int n;

long long f[max_n];

void doit()

int main()

return 0;

}

poj2411)用1 * 22 * 1的小矩形覆蓋n * m的大矩形,有多少種方案。

剛剛n = 3時,我們可以人為知道它有哪些狀態,但是這是特殊情況,如果n為任意值呢?顯然狀態就不止幾個,所以要先找出所有可行的狀態,用dfs搜尋出來。因為dfs狀態還是乙個比較費時的演算法,為了加快速度,我們把短的那個當做寬來列舉狀態。首先,我們規定:放置橫著和豎著的矩形時第i個格仔的狀態為1;而豎矩形的上乙個和不放置矩形的狀態為0;可以畫一畫進一步理解這個規定。而且因為這是我們人為規定的,所以轉移時總能找到下乙個合法狀態。

畫過圖基本就可以知道如何轉移了(i為當前行第i個格仔,即第i列,now為當前行的狀態,pre為上一行的狀態):1、放置豎矩形,當第i列為1時,那麼pre的第i列就得是0 ( i = i + 1, now << 1 | 1, pre << 1 );2、放置豎矩形,當第i列為0時,那麼pre的第i列可以為1 ( i = i + 1, now << 1, pre << 1 | 1 );3、放置橫矩形,因為橫矩形佔兩個格仔,且nowpre都為1,所以( i = i + 2, now << 2 | 3, pre << 2 | 3);    最後把now, pre存在乙個二維陣列中,path[ tot ][ 0 ] = pre,path[ tot ][ 1 ] = now;

然後就要進行行的轉移,很簡單:設f[ i ][ path[ j ] ]表示鋪滿前i行狀態為第j個的方案數;轉移為f[ i + 1 ][ path[ j ][ 1 ] ] += f[ i ][ path[ j ][ 0 ] ];因為要全部鋪滿,所以到最後一行時,狀態應該全部為1。所以答案為f[ n ][ (1 << m) - 1];

#include #include #include using namespace std;

const int max_n = 15;

int n, m, tot = 0;

long long f[max_n][2500];

int path[14000][2];

void dfs(int l, int now, int pre)

dfs(l + 1, now << 1 | 1, pre << 1);

dfs(l + 1, now << 1, pre << 1 | 1);

dfs(l + 2, now << 2 | 3, pre << 2 | 3);

}void doit()

printf("%lld\n", f[n][(1 << m) - 1]);

}int main()

return 0;

}

1 * 22 * 1的矩形完全覆蓋4 * n的矩形的方案數

和上一道題差不多,不同是的是n比較大,要用矩陣乘法優化

#include #include using namespace std;

struct nodea;

int n, m, w;

void dfs(int l, int now, int pre)

dfs(l + 1, now << 1 | 1, pre << 1);

dfs(l + 1, now << 1, pre << 1 | 1);

dfs(l + 2, now << 2 | 3, pre << 2 | 3);

}node mul(node a, node b)

} return c;

}node gao(node a, int k)

return p;

}void doit()

node ans = gao(a, n);

printf("%lld\n", ans.mat[15][15]);

}int main()

return 0;

}

游標那點事兒

兩種迴圈跳出方法 1 稍顯複雜點 create procedure dbo.usp cralltables client id varchar 256 asdeclare table name varchar 50 set nocount on declare t name cur cursor l...

imu那點事兒

一.對於bosch晶元的總結 offset 是指sensor的零偏。datasheet 裡邊描述的是在不同的情況下offset 的spec.offa,int 表示sensor 出廠時最初的offset spec,是component level offa,board 表示sensor 在貼到pcb ...

Spring MVC那點事兒

1 spring mvc的啟動原理?spring mvc是基於ioc容器的,因此需要先建立ioc容器,才能建立對應的spring mvc執行環境。ioc容器是通過contextloaderlistener建立的,這個類通過servletcontext建立。在springmvc中,最核心的思想其實就是...