题意:求至少连续的H为k的个数,因为最多有2^100这么多可能,所以要用到大数,这次看了别人的代码写了大数的类,要不分开写函数有太多,还有的是这道题用到了dp,我们可以从总的可能中减去连续的H不超过K-1的可能,所以这道前跟之前的一道题连续W的是差不多的,设dp[i][j]表示前i次连续的H不超过j的个数,,对于第i次,不考虑条件的话是2*dp[i-1][j],那么就还是分两种情况分析,当i==j+1的时候,比如k=4,就是(H,H,H,H,i)显然只有连续j+1个H是不符合条件的,当i>j+1的时候,假设前面有连续j个H,比如连续的不超过4吧,就是这种情况:...T H H H H (i),那么我们在考虑第i位的时候肯定是要考虑当i=H的时候,这中情况是不正确的,而这种情况有f(i-j-2)个,就是T前面已经满足的可能个数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 500;
struct Bigint{
int f[MAXN],len;
Bigint(){
memset(f,0,sizeof(f));
len = 0;
}
void fixlen(Bigint &B,int l){
while (B.f[l] == 0 && l)
l--;
B.len = l + 1;
}
void print(){
for (int i = len-1; i >= 0; i--)
printf("%d",f[i]);
printf("\n");
}
Bigint operator +(const Bigint &B){
int i,la=len,lb=B.len;
Bigint C;
for (i = 0;; i++){
if (i < la && i < lb)
C.f[i] += f[i] + B.f[i];
else if (i <la)
C.f[i] += f[i];
else if (i < lb)
C.f[i] += B.f[i];
else break;
if (C.f[i] > 10){
C.f[i] -= 10;
C.f[i+1]++;
}
}
fixlen(C,i);
return C;
}
Bigint operator -(const Bigint &B){
int i,la=len,lb=B.len;
Bigint C;
for (i = 0; i < la; i++){
C.f[i] += f[i];
if (i < lb)
C.f[i] -=B.f[i];
if (C.f[i] < 0)
C.f[i+1]--,C.f[i] += 10;
}
fixlen(C,i);
return C;
}
Bigint operator *(const int &a){
Bigint C;
int i,t=0;
for (i = 0;; i++){
if (i >= len && t == 0)
break;
if (i < len)
t = t + f[i] * a;
C.f[i] = t % 10;
t /= 10;
}
fixlen(C,i);
return C;
}
Bigint(int t){
f[0] = 0,len = 0;
while (t){
f[len++] = t % 10;
t /= 10;
}
if (!len)
len = 1;
}
};
Bigint s[MAXN],dp[MAXN][MAXN];
void init1(){
s[0] = Bigint(1);
for (int i = 1; i <= 100; i++)
s[i] = s[i-1] * 2;
}
void init2(){
int i,j,k;
for (i = 0; i <= 100; i++)
dp[i][0] = Bigint(1);
for (i = 0; i <= 100; i++)
dp[0][i] = Bigint(1);
for (i = 1; i <= 100; i++){
for (j = 1; j <= 100; j++){
if (i == 1 && j == 1)
dp[i][j] = 2;
else if (j <= i){
dp[i][j] = dp[i-1][j] * 2;
if (i-j-2 >= 0)
dp[i][j] = dp[i][j] - dp[i-j-2][j];
else if (j < i)
dp[i][j] = dp[i][j] - Bigint(1);
}
else dp[i][j] = dp[i][j-1];
}
}
}
int main(){
int n,k;
init1();
init2();
Bigint ans;
while (scanf("%d%d",&n,&k) != EOF){
ans = s[n] - dp[n][k-1];
ans.print();
}
return 0;
}