1. 程式人生 > >poj 2440 DNA 遞推在模下存在迴圈節

poj 2440 DNA 遞推在模下存在迴圈節

題意和分析:

       題意都是廢話,用動態規劃列個方程化下簡,最後也是這題有意思的地方是求a(n)=a(n-1)+a(n-3)+a(n-4) 在模2005下的值。

       你可能會說,這個簡單啊,弄個數組,搞個for迴圈就行啊,沒錯,但這是O(n)。能快點麼?

       嗯,那用矩陣相乘表示遞推,在矩陣乘法結合律的保證下冪運算加速足夠快了吧?嗯,是快不少,但這是O(logn),還不夠快。

       這題就是這麼狠,要O(1)的演算法,求a(n)=a(n-1)+a(n-3)+a(n-4) 在模2005下的值。

       如果遞推階數K固定模M固定,那麼K階遞推在模M下是存在迴圈節的,假設迴圈節為t,a(t+n)=a(n),令n=0得a[t]=a[0],這題的a[0]是1,我們搞個輔助程式從i=K開始求a[i],當a[i]=a[0]=1時,我們的i就是迴圈節t,那麼不管n是啥我們輸出a[n%t]就可以了,這題t試出來是200,所以程式碼:

//poj 2440
//sep9
#include <iostream>
using namespace std;

int main()
{
	int a[256]={1,2,4,6},n;
	for(int i=4;i<200;++i)
		a[i]=(a[i-1]+a[i-3]+a[i-4])%2005;
	while(scanf("%d",&n)==1)
		printf("%d\n",a[n%200]);	
	return 0;	
}

========================休息&發呆分割線========================================================

    那麼,關鍵的問題來了,你質疑麼?為什麼 如果遞推階數K固定模M固定,那麼K階遞推在模M下是存在迴圈節的?

    

  因為階數K固定,任意的a[n]只與a[n-k],[n-k+1]....a[n-1]有關,而因為模M固定,a[n-k],[n-k+1]....a[n-1]總共的狀態數固定小於M^K,M^K是個定值,也就是說在最極限情況下,a[n+M^k]=a[n],故存在迴圈節t使得a[n+t]=a[n],t<M^k。

   這個迴圈節問題以前遇到這種噁心的題就想不明白,今天不知道為啥突然想清楚了-。-,好像也很簡單的樣子。