HDU 6185 Covering (2017 廣西邀請賽重現賽)(矩陣快速冪)
阿新 • • 發佈:2019-02-07
題意:用1x2或者2x1的地毯去鋪滿4xN的地面。給定N,問方案數.
(偶見DFS暴力搜尋前10個結果,學習中,稍後貼上)
(偶見DFS暴力搜尋前10個結果,學習中,稍後貼上)
解法:推匯出公式後,轉換成矩陣快速冪求解即可.
/*dfs暴力求解,便於找規律*/ #include<bits/stdc++.h> using namespace std; typedef long long ll; bool book[7][1007]; int n, cnt; bool findpos(int &x, int &y) { for(int i=1 ; i<=4 ; i++) { for(int j=1 ; j<=n ; j++) { if(!book[i][j]) { x = i, y = j; return false; } } } return true; } void dfs(int x, int y) { if(!book[x+1][y] && x<4) { book[x][y] = book[x+1][y] = true;//縱向 int newx, newy; if(findpos(newx, newy)) {//已經填滿 book[x][y] = book[x+1][y] = false;//登出掉 cnt++; return ; } dfs(newx, newy);//從未填滿的地方開始繼續dfs book[x][y] = book[x+1][y] = false;//恢復 } if(!book[x][y+1] && y<n) {//橫向 book[x][y] = book[x][y+1] = true; int newx, newy; if(findpos(newx, newy)) { book[x][y] = book[x][y+1] = false; cnt++; return ; } dfs(newx, newy); book[x][y] = book[x][y+1] = false; } } int main(){ while(~scanf("%d", &n)){ cnt=0; dfs(1, 1); cout << cnt<<endl; } }
/* 推導公式:F[i] = F[i-1] + 5*F[i-2] + F[i-3] - F[i-4] */ #include<bits/stdc++.h> #define rep(i, a, b) for(int i=(a); i<(b); ++i) using namespace std; typedef long long ll; const int maxn = 4; const ll mod= 1e9+7; struct Matrix{ ll tmp[maxn][maxn]; }a; void init() { rep(i, 0, maxn){ rep(j, 0, maxn){ a.tmp[i][j]=0; } } a.tmp[0][0]=a.tmp[0][2]=1; a.tmp[0][1]=5; a.tmp[0][3]=-1; a.tmp[1][0]=a.tmp[2][1]=a.tmp[3][2]=1; return; } Matrix mul(Matrix a,Matrix b) { Matrix ans; rep(i, 0, maxn) rep(j, 0, maxn){ ans.tmp[i][j]=0; rep(k, 0, maxn){ ans.tmp[i][j]+=(a.tmp[i][k]*b.tmp[k][j]+mod)%mod; ans.tmp[i][j]%=mod; } } return ans; } void fun(Matrix ans,ll k) { rep(i,0,maxn){ rep(j, 0, maxn) { a.tmp[i][j]=(i==j); } } while(k){ if(k%2) a=mul(a,ans); ans=mul(ans,ans); k/=2; } return ; } int main(){ //freopen("in.txt", "r", stdin); Matrix t; ll n; rep(i, 0, maxn){ rep(j, 0, maxn){ t.tmp[i][j]=0; } } t.tmp[0][0]=36; t.tmp[1][0]=11; t.tmp[2][0]=5; t.tmp[3][0]=1; while(~scanf("%lld",&n)) { init(); if(n<=4){ printf("%lld\n",t.tmp[4-n][0]); continue; } fun(a,n-4); a=mul(a,t); printf("%lld\n",a.tmp[0][0]%mod); } return 0; }