题目大意是有n个盒子,每个盒子里面分别装的是U和L,然后当有3个或者大于3个的U在一块时,被叫做危险的组合,那么给一个数字n,要求它危险组合数的个数。
解答:f[i]表示有i个盒子时,危险组合的数目,分两种情况:
1.前i-1个盒子中已经出现了危险组合,那么第i个组合可以任意为U,L,个数为2*f[i-1]。
2.第i个盒子为U时,恰好出现了危险组合,那么最后三个就是为UUU,倒数第四个必定为L,而前i-4个盒子只要不出现满足危险组合条件的情况就好了,个数为pow(2,i-4) - f[i - 4]。
二者相加即为所求的答案。
#include "stdio.h"
#include "string.h"
#include "math.h"
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
#define MAXM 1
#define MAXN 1
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define Mem(a,b) memset(a,b,sizeof(a))
int Mod = 1000000007;
double pi = acos(-1.0);
double eps = 1e-6;
typedef struct{
int f,t,w,next;
}Edge;
Edge edge[MAXM];
int head[MAXN];
int kNum;
typedef long long LL;
void addEdge(int f, int t, int w)
{
edge[kNum].f = f;
edge[kNum].t = t;
edge[kNum].w = w;
edge[kNum].next = head[f];
head[f] = kNum ++;
}
int N;
LL f[35];
LL pow2[35];
void func(){
Mem(f, 0);
pow2[0] = 1;
for(int i = 1; i <= 30; i ++){
pow2[i] = 2 * pow2[i-1];
}
f[3] = 1;
for(int i = 4; i <= 30; i ++){
f[i] += 2 * f[i-1];
f[i] += ( pow2[i-4] - f[i-4] );
}
}
int main()
{
// freopen("d:\\test.txt", "r", stdin);
func();
while(cin>>N){
if( N < 1 )
break;
cout<<f[N]<<endl;
}
return 0;
}