首页 > 代码库 > [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天