Critical Mass UVA - 58 危险的组合 递推

题目链接

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

#include 
using namespace std;
int f[31],g[31];
int main(int argc, char *argv[]) {
	g[0] = 1; g[1] = 2, g[2] = 4;
	for(int n = 3; n <= 30; n++){
		f[n] = 1 << (n-3);
		for(int i = 2; i <= n-2; i++)
			f[n] += g[i-2] * (1 << (n-i-2));
		g[n] = (1 << n) - f[n];
	}
	int n;
	while(cin>> n && n)
		cout<< f[n] << "\n";
	return 0;
}

 

你可能感兴趣的:(数论,算法竞赛入门经典(第二版))