题目给出n,问你0-(2^n-1)之间存在多少没有连续1出现的数
先找1连续出现数的个数
列出几个数就可以找到规律了
0:【0】0个
1:【00】【01】0个
2:【00】【01】【10】【11】0+0+1 = 1个
3:【00】【01】【10】【11】
【100】【101】【110】【111】
上下两行对比即可发现规律0+1+2 = 3
对于dp【i】,把0-(2^i-1)等分成前后两段
前一段即为dp【i-1】,后一段的前半部分为dp【i-2】,后半段的后半部分必然存在连续1
所以dp【i】 = dp【i-1】+dp【i-2】+pow(2,i-2)
代码如下:
#include <cstdio>
#define LL long long
using namespace std;
LL dp[50];
void init() {
LL tmp = 1ll;
dp[0] = dp[1] = 0;
for(int i=2; i<=45; ++i) {
dp[i] = dp[i-1]+dp[i-2]+tmp;
tmp *= 2;
}
tmp = 1ll;
for(int i=0; i<=45; ++i) {
dp[i] = tmp - dp[i];
tmp *= 2;
}
}
int main(void) {
int T, n;
init();
scanf("%d", &T);
for(int t=1; t<=T; ++t) {
scanf("%d", &n);
printf("Scenario #%d:\n%lld\n\n", t, dp[n]);
}
return 0;
}
/*
1111 1110 1101 1100 1011 1010 1001 1000 0111 0110 0101 0100 0011 0010 0001 0000
dp[0] = 0;
dp[1] = 0;
dp[2] = 1;
dp[3] = dp[1]+dp[2]+2^1 = 3;
dp[4] = dp[2]+dp[3]+2^2 = 8;
dp[5] = dp[3]+dp[4]+2^3 = 19;
dp[1] = 0;
dp[2] += dp[0]+dp[0];
dp[3] += dp[2]+dp[2];
dp[4] += dp[3]+dp[3];
*/