程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 1009 HNOI2008 GT考試 KMP算法+矩陣乘法

BZOJ 1009 HNOI2008 GT考試 KMP算法+矩陣乘法

編輯:C++入門知識

BZOJ 1009 HNOI2008 GT考試 KMP算法+矩陣乘法


題目大意:給定長度為m的數字串s,求不包含子串s的長度為n的數字串的數量
n<=10^9 光看這個O(n)就是掛
我們不考慮這個 令f[i][j]為長度為i的數字串中最後j位與s中的前j位匹配的方案數
比如當s為12312時 f[i][3]表示長度為i,以123結尾且不包含子串”12312“的方案數
a[x][y]為f[i-1][x]轉移至f[i][y]的方案數
換句話說(可能描述不清楚) a[x][y]為s的長度為x的前綴加上一個數字後 後綴可以與最長長度為y的前綴匹配 這個數字可以有多少種
比如說12312 這個數字串生成的a數組為(數組從0開始):
9 1 0 0 0 0
8 1 1 0 0 0
8 1 0 1 0 0
9 0 0 0 1 0
8 1 0 0 0 1
a[2][1]=1 表示長度為2的前綴加上一個'1'之後最多與長度為1的前綴匹配
a[4][0]=8 表示長度為4的前綴加上'1''2'以外的數就變成了長度為0的前綴
但是a[x][5]表示完全匹配,不滿足要求的題意,所以我們矩陣乘法時不考慮這一列
我們發現f[i-1]乘上這個矩陣就變成了f[i] 這個矩陣怎麼求呢?KMP算法,對於每個長度的前綴枚舉下一個字符進行轉移 具體寫法詳見代碼
f初值是f[0][0]=1,f[0][x]=0 (x>0)
於是最後我們只需要取答案矩陣的第一行即可

去網上找了一堆題解才看懂0.0 這裡寫的稍微詳細一點吧

#include
#include
#include
#include
using namespace std;
struct matrix{
	int xx[22][22];
	int* operator [] (int x)
	{
		return xx[x];
	}
}a,b;
int n,m,p,ans;
char s[100];
int next[100];
void operator *= (matrix &x,matrix &y)
{
	int i,j,k;
	matrix z;
	memset(&z,0,sizeof z);
	for(i=0;i>=1;
	}
}
int main()
{
	int i;
	cin>>n>>m>>p;
	scanf("%s",s+1);
	KMP();
	for(i=0;i

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved