15年第六届蓝桥杯第九题_(矩阵快速幂优化的动态规划)
壘骰子
賭圣atm晚年迷戀上了壘骰子,就是把骰子一個壘在另一個上邊,不能歪歪扭扭,要壘成方柱體。
經過長期觀察,atm 發現了穩定骰子的奧秘:有些數字的面貼著會互相排斥!
我們先來規范一下骰子:1 的對面是 4,2 的對面是 5,3 的對面是 6。
假設有 m 組互斥現象,每組中的那兩個數字的面緊貼在一起,骰子就不能穩定的壘起來。
atm想計算一下有多少種不同的可能的壘骰子方式。
兩種壘骰子方式相同,當且僅當這兩種方式中對應高度的骰子的對應數字的朝向都相同。
由于方案數可能過多,請輸出模 10^9 + 7 的結果。
不要小看了 atm 的骰子數量哦~
「輸入格式」
第一行兩個整數 n m
n表示骰子數目
接下來 m 行,每行兩個整數 a b ,表示 a 和 b 數字不能緊貼在一起。
「輸出格式」
一行一個數,表示答案模 10^9 + 7 的結果。
「樣例輸入」
2 1
1 2
「樣例輸出」
544
「數據范圍」
對于 30% 的數據:n <= 5
對于 60% 的數據:n <= 100
對于 100% 的數據:0 < n <= 10^9, m <= 36
資源約定:
峰值內存消耗 < 256M
CPU消耗 < 2000ms
感覺挺有難度的一題。。。最開始想到了動態規劃,發現數據太大。。。
看了題解:博主最初用的常規dp,dp[i][j]:第i層,j點在上面的種數;dp[i][j]=dp[i][j]+dp[i-1][x](x的對面與j不沖突),我最初的想法也跟這個差不多,只是時間復雜度不夠。。。
然后看了樓主的第二篇用矩陣快速冪優化的解法,很精辟。http://blog.csdn.net/lonverce/article/details/45169285
可以用矩陣快速冪來優化一些不滿足時間復雜度的dp,但是遞推式很重要,想不出遞推式都是白搭。。。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<string> using namespace std; #define MOD 1000000007 #define LL long long struct Matrix {int row,col;LL matr[8][8];Matrix() {}Matrix(int r,int c,int num){row=r;col=c;for(int i=1; i<=r; i++)for(int j=1; j<=c; j++)matr[i][j]=num;} };Matrix matr_multi(Matrix m1,Matrix m2) //矩陣乘法 {Matrix m3(m1.row,m2.col,0);for(int i=1; i<=m1.row; i++)for(int j=1; j<=m2.col; j++)for(int k=1; k<=m1.col; k++)m3.matr[i][j]=(m3.matr[i][j]+m1.matr[i][k]*m2.matr[k][j])%MOD;return m3; }void matr_givevalue(Matrix& a,Matrix b) {a.row=b.row;a.col=b.col;for(int i=1; i<=a.row; i++)for(int j=1; j<=a.col; j++)a.matr[i][j]=b.matr[i][j]; }Matrix matr_pow(Matrix m1,int k) //矩陣快速冪 {Matrix m2;matr_givevalue(m2,m1);k--;while(k>0){if(k&1)m2=matr_multi(m2,m1);m1=matr_multi(m1,m1);k>>=1;}return m2; }LL PowMod(LL n,int k) //常規快速冪 {LL res=1;while(k>0){if(k&1)res=(res*n)%MOD;n=(n*n)%MOD;k>>=1;}return res; }void matr_output(Matrix m) {for(int i=1; i<=m.row; i++){for(int j=1; j<=m.col; j++)cout<<m.matr[i][j]<<" ";cout<<endl;} } int main() {Matrix conflict(6,6,1);Matrix m2(1,6,1);int nn,mm;scanf("%d%d",&nn,&mm);for(int i=0; i<mm; i++){int a,b;scanf("%d%d",&a,&b);int bb=b+3,aa=a+3;if(bb>6)bb%=6;if(aa>6)aa%=6;conflict.matr[a][bb]=0; //設置conflict,這個地方要注意conflict.matr[aa][b]=0;}Matrix m1;m1=matr_pow(conflict,nn-1);m2=matr_multi(m2,m1);LL power=PowMod(4,nn);LL res=0;for(int i=1; i<=6; i++)res=(res+m2.matr[1][i])%MOD;res=(res*power)%MOD;printf("%I64d\n",res);return 0; }?
轉載于:https://www.cnblogs.com/jasonlixuetao/p/6491338.html
總結
以上是生活随笔為你收集整理的15年第六届蓝桥杯第九题_(矩阵快速幂优化的动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: golang工程打包不发布
- 下一篇: 计算机网络运输层之多路复用与多路分解