首页 > 代码库 > [CDOJ]1587_失恋772002天

[CDOJ]1587_失恋772002天

链接:http://acm.uestc.edu.cn/#/problem/show/1587

题意:失恋772002天

给定一个整数N,对一个仅有三种字符组成的长度为N的字符串,问有多少种排列满足  任意三个连续的字符x,y,z中,x=y或者x=z或者y=z成立(也就是三个不能不同)

得到结果要取模后输出

 


 

题解:

水题0。0 ( 啪 x )

显然n=1的时候结果为3

假设S(n)表示长度为n(n>1)的所有满足题意的字符串的集合,那么我构造两个子集(划分):

S1(n):S中的字符串里最后两个字符不一样的字符串组成的集合

S2(n):S中的字符串里最后两个字符一样的字符串组成的集合

显然S1(n)与S2(n)不相交,而且S(n)等于S1(n)并上S2(n)

记D(n)为S1(n)的元素个数,A(n)为S2(n)的元素个数

那么我们可以知道,当n>2时

S(n-1)中的字符串同样也可以划分为S1(n-1)和S2(n-1):

  1.对于S1(n-1)中的字符串:

    1.1添加跟倒数第二个字符一样的那个字符可以变成S1(n)中的字符串

    1.2添加跟最后一个字符一样的那个字符可以变成S2(n)中的字符串

  2.对于S2(n-1)中的字符串:

    2.1添加跟后面那个字符不一样的那个字符可以变成S1(n)中的字符串(每个字符串都有两种添加的选择)

    2.2添加跟后面那个字符一样的那个字符可以变成S2(n)中的字符串

由1.1和2.1,有D(n) = D(n-1) + 2*A(n-1) (n>2)

由1.2和2.2,有A(n) = D(n-1) + A(n-1) (n>2)

而 D(2) = 6,A(2) = 3

为此,得到了递推式,最后结果为

3  (n=1)

D(n)+A(n) (n>=2)

其实对于上面那两个式子可以根据递推关系推导出只跟n有关的关系式,不过我懒得了(x)

#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<iostream>
#include<string>
#include<sstream>
//stringstream ss(line)
#include<algorithm>
//sort(a,a+n,cmp)
//p=lower_bound(a,a+n,x)-a+1(大于或等于x的第一个位置)
#include<vector>
#include<bitset>
//bitset<N> xx

using namespace std;
const int MOD = 554056561;

int main(){
	int N;
	scanf("%d",&N);
	int D[2],A[2];
	if(N==1)	printf("%d",3);
	else if(N==2)	printf("%d",9);
	else{
		D[0]=6,A[0]=3;
		for(int i=3;i<=N;i++){
			A[i%2]=(A[(i+1)%2]+D[(i+1)%2])%MOD;
			D[i%2]=(2*A[(i+1)%2]+D[(i+1)%2])%MOD;
		}
		printf("%d",(A[N%2]+D[N%2])%MOD);
	}
	return 0;
}

  

[CDOJ]1587_失恋772002天