hdu5318 The Goddess Of The Moon (矩阵高速幂优化dp)

Posted yangykaifa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5318 The Goddess Of The Moon (矩阵高速幂优化dp)相关的知识,希望对你有一定的参考价值。

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5318

题意:给定n个数字串和整数m,规定若数字串s1的后缀和数字串s2的前缀同样且长度≥2,则s2能够拼接在s1的后面,每一个串能够反复用,问拼接m个数字串有多少种方法。

n<=50,m<=1e9

分析:定义dp[i][j]为拼接了i个串而且这个长串以s[j](输入的第j个数字串)结尾的方案数。

那么有

for(int i=1;i<=n;i++)
   dp[1][i]=1;
for(int i=2;i<=m;i++)
	for(int j=1;j<=n;j++)
		for(int k=1;k<=n;k++)
			if(connect(j,k))
				dp[i][j]+=dp[i-1][k];

     然后,之前非常早有人跟我讲过用矩阵能够算路径数,,,,,,。能够利用上述递推式构造矩阵从而高速计算出结果。定义:A矩阵里面的元素ai表示以s[i]结尾的串的方案数。

B矩阵bij表示s[j]能够拼接在s[i]的后面。

那么结果矩阵就是A*B^(m-1);

比如:n=2,m=5,s[1]="322",s[2]="22",那么

A={1,1}
B={1,1,
   0,1}

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 55;
const int mod = 1000000007;
int N,M,use[100];
char s1[20],s2[20];
struct Matrix
{
	long long M[maxn][maxn];
	Matrix(){memset(M,0,sizeof(M));}
}U,P;
Matrix Multi(Matrix &a,Matrix &b)
{
	Matrix ans;
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			for(int k=0;k<N;k++)
				ans.M[i][j]=(ans.M[i][j]+a.M[i][k]*b.M[k][j])%mod;
	return ans;
}
Matrix Power(Matrix a,int n)
{
	Matrix ans=U;
	while(n)
	{
		if(n&1)
			ans=Multi(ans,a);
		n>>=1;
		a=Multi(a,a);
	}
	return ans;
}
bool Match(int a,int b)  //ok
{
	sprintf(s1,"%d",a);
	sprintf(s2,"%d",b);
	int len1=strlen(s1),len2=strlen(s2);
	for(int i=len1-1,j=0;i>=0 && j<len2;i--,j++)
		if(len1-i>=2 && string(s1+i,s1+len1)==string(s2,s2+j+1))
			return true;
	return false;
}
void Init()
{
	memset(P.M,0,sizeof(P.M));
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			if(Match(use[i],use[j]))
				P.M[i][j]=1;
}
long long GetAns(Matrix &ans)
{
	long long ret=0;
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			ret+=ans.M[i][j];
	return ret%mod;
}
int main()
{
	for(int i=0;i<maxn;i++)
		U.M[i][i]=1;
	int ncase,i,j;
	scanf("%d",&ncase);
	while(ncase--)
	{
		scanf("%d%d",&N,&M);
		for(i=0;i<N;i++)
			scanf("%d",&use[i]);
		sort(use,use+N);
		N=unique(use,use+N)-use;
		Init();
		Matrix ans=Power(P,M-1);
		printf("%I64d\n",GetAns(ans));
	}
	return 0;
} 

以上是关于hdu5318 The Goddess Of The Moon (矩阵高速幂优化dp)的主要内容,如果未能解决你的问题,请参考以下文章

hdu5318 The Goddess Of The Moon (矩阵高速幂优化dp)

The goddess, the bird, the bell, the temptation of the house

number field is the union of the set of all strings and the set of all numbers. The set of things th

Codeforces 622F The Sum of the k-th Powers

The 16th tip of DB Query Analyzer

hdu 2985 The k-th Largest Group 树状数组求第K大