題目:
題意:
有n個硬幣排成一排,有正有反,問有2個以上連續的相同硬幣有幾種方案
分析:
典型的推公式用矩陣快速冪求解的題目。
(偷個懶,貼個別人的推導)
長度為 n 的 01 串一共有 2^n 種不同的排列方法 ,設 f(n) 為長度是 n 的不包含連續 3 個或以上相同的 1 或 0 的 01 串 ,則 f(1)=2,f(2)=4,f(3)=6,f(4)=10
當 n>4 的時候 , 分情況考慮 :
1、 如果是以 00 或者 11 結尾 , 則分別有 f(n-2)/2 種情況 , 加起來就是 f(n-2) 種 .
2、 如果是以 01 或者 10 結尾 , 則第 n 個字元要和第 n-1 個字元不一樣 , 那麼分別有 f(n-1)/2 種 , 加起來就是 f(n-1)
則統計起來就是 f(n)=f(n-1)+f(n-2), 題目要求的是包含連續三個相同的 0 或 1 串的串數 , 那就是用 a[n]=(2^n-f(n))%10007.
然而這樣還不好求 , 先不看 %10007, 轉換成遞推公式是 a[n]=a[n-1]+a[n-2]+2^(n-2),
轉換成矩陣 :
a[n] 1 1 1 a[n-1]
a[n-1] = 1 0 0 * a[n-2]
2^(n-1) 0 0 2 2^(n-2)
這樣就可以用矩陣冪快速算出 a[n], 複雜度為 o(logn)
#include
#include
#include
using
namespace
std;
const
int n=3;
const
int mod=10007;
struct mat;
mat mul(mat a,mat b)
mat qmod(mat a,int k)
return c;
}int main()
; while(~scanf("%d",&n))
mat c=qmod(a,n-4);
int ans=c.mat[0][0]*6+c.mat[0][1]*2+c.mat[0][2]*8;
printf("%d\n",ans%mod);
}return
0;}
HDU 2842 遞推 矩陣快速冪
題目大意 棒子上套環。第i個環能拿下的條件是 第i 1個環在棒子上,前i 2個環不在棒子上。每個環可以取下或放上,cost 1。求最小cost。mod 200907。解題思路 題目意思非常無聊,感覺是yy的。設 dp i 為取第i個環時的總cost。dp 1 1 dp 2 2 前兩個環取下是沒有條件...
HDU 2842 遞推 矩陣快速冪
題目大意 棒子上套環。第i個環能拿下的條件是 第i 1個環在棒子上,前i 2個環不在棒子上。每個環可以取下或放上,cost 1。求最小cost。mod 200907。解題思路 題目意思非常無聊,感覺是yy的。設 dp i 為取第i個環時的總cost。dp 1 1 dp 2 2 前兩個環取下是沒有條件...
HDU5950 矩陣快速冪(巧妙的遞推)
題意 f n 2 f n 2 f n 1 n 4 思路 對於遞推題而言,如果遞推n次很大,則考慮矩陣快速冪的方式推出遞推式,計算出累乘的矩陣 本題遞推式 本題的遞推式子雖然已經給出,但是由於n 4的關係,直接是無法使用這個f n 2 f n 2 f n 1 n 4遞推完成矩陣的推導的,而是可以先處理...