题意:有一道光射入3层玻璃,光可以在任何两层玻璃之间反弹,求反弹N次有多少种不同的路径.
思路:一块玻璃有正反面之分,如果光射在(或者反弹到)第i层的正面,那么只能是从第1至第i-1层的反面反射到第i面的正面上,同样第i层的反面只能是从第i+1到最后一层的正面上反射到第i层的反面上.
设dp[i][j][2]表示第i次反射在第j层的正反面的路径数,那么答案就是sum(dp[n][i][0] + dp[n][i][1])
dp[i][j][0] = sum(dp[i - 1][k][1] | 0<= k < j)
dp[i][j][1] = sum(dp[i - 1][k][0] | j < k < 4)
base cases:dp[1][1][0] = dp[1][2][0] = dp[1][3][0] = 1.刚开始光只从上面射入,那么只能到1,2,3层的正面.
#include <cstdio>
using namespace std;
const int MAX = 61;
int main(int argc, char const *argv[]){
long long dp[MAX][4][2];
dp[1][1][0] = dp[1][2][0] = dp[1][3][0] = 1;
for(int i = 2; i < MAX; ++i){
for(int j = 0; j < 4; ++j){
for(int k = 0; k < j; ++k){
dp[i][j][0] += dp[i - 1][k][1];
}
for(int k = j + 1; k < 4; ++k){
dp[i][j][1] += dp[i - 1][k][0];
}
}
}
int n;
while(scanf("%d", &n) == 1){
if(n == 0){
printf("1\n");
continue;
}
long long ans = 0;
for(int i = 0; i < 4; ++i){
ans += dp[n][i][0] + dp[n][i][1];
}
printf("%lld\n", ans);
}
return 0;
}