危险的组合Critical Mass【数轮+递推】

传送门
设答案为 f ( n ) f(n) f(n)。既然有3个U放在一起,可以根据这3个U的位置分类——对,根据前面的 经验,要根据“最左边的3个U”的位置分类。假定是 i 、 i + 1 i、i+1 ii+1 i + 2 i+2 i+2这3个盒子,则前 i − 1 i-1 i1个盒子不 能有3个U放在一起的情况。设n个盒子“没有3个U放在一起”的方案数为 g ( n ) = 2 n − f ( n ) g(n)=2^n-f(n) g(n)=2nf(n),则前i-1 个盒子的方案有 g ( i − 1 ) g(i-1) g(i1)种。后面的 n − i − 2 n-i-2 ni2个盒子可以随便选择,有 2 n − i − 2 2n-i-2 2ni2种。根据乘法原理和加 法原理, f ( n ) = ∑ i = 1 n − 2 h ( i − 1 ) ∗ 2 n − i − 2 f(n)=\sum^{n-2}_{i=1}h(i-1)*2^{n-i-2} f(n)=i=1n2h(i1)2ni2
遗憾的是,这个推理是有瑕疵的。即使前i-1个盒子内部不出现3个U,仍然可能和 i 、 i + 1 i、i+1 ii+1 i + 2 i+2 i+2组成3个U。正确的方法是强制让第 i − 1 i-1 i1个盒子(如果存在)放L,则前i-2个盒子内部不能出现连续的3个U。因此 f ( n ) = 2 n − 3 + ∑ i = 1 n − 2 h ( i − 1 ) ∗ 2 n − i − 2 f(n)=2^{n-3}+\sum^{n-2}_{i=1}h(i-1)*2^{n-i-2} f(n)=2n3+i=1n2h(i1)2ni2 ,边界 是 f ( 0 ) = f ( 1 ) = f ( 2 ) = 0 。 g ( 0 ) = 1 , g ( 1 ) = 2 , g ( 2 ) = 4 f(0)=f(1)=f(2)=0。g(0)=1,g(1)=2,g(2)=4 f(0)=f(1)=f(2)=0g(0)=1g(1)=2g(2)=4。注意上式中的 2 n − 3 2^n-3 2n3对应于 i = 1 i=1 i=1的情况。

#include
using namespace std;
const int N=35;
int f[N],g[N];
int main(){
	int n;
	f[0]=f[1]=f[2]=0;
	g[0]=1,g[1]=2,g[2]=4;
	for(int i=3;i<=30;i++){
		f[i]=(1<<(i-3));
		for(int j=2;j<=i-2;j++)
			f[i]+=g[j-2]*(1<<(i-j-2));
		g[i]=(1<<i)-f[i];
	}
	while(cin>>n,n){
		cout<<f[n]<<endl;
	}
}

你可能感兴趣的:(数论,递推)