题意:给出n,然后要组成n,只有两个字符H和T,然后再给出一个k,要求最少出现连续的k个H
题解:参考传送门,注意这个题要使用高精度,我使用的是俞书的高精度板子
附上代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e2+50;
const int ten[4]={1,10,100,1000};
const int maxl=1000;
struct BigNumber{
int d[maxl];
BigNumber (string s){
int len=s.size();
d[0]=(len-1)/4+1;
int i,j,k;
for(i=1;i<maxl;i++){
d[i]=0;
}
for(i=len-1;i>=0;i--){
int j=(len-i-1)/4+1;
int k=(len-i-1)%4;
d[j]+=ten[k]*(s[i]-'0');
}
while(d[0]>1&&d[d[0]]==0){
d[0]--;
}
}
BigNumber(){
*this=BigNumber(string("0"));
}
string toString(){
string s("");
int i,j,temp;
for(i=3;i>=1;i--){
if(d[d[0]]>=ten[i]){
break;
}
}
temp=d[d[0]];
for(j=i;j>=0;j--){
s=s+(char)(temp/ten[j]+'0');
temp%=ten[j];
}
for(i=d[0]-1;i>0;i--){
temp=d[i];
for(int j=3;j>=0;j--){
s=s+(char)(temp/ten[j]+'0');
temp%=ten[j];
}
}
return s;
}
}zero("0"),d,temp,mid1[maxn],dp[maxn][2];
BigNumber operator + (const BigNumber &a,const BigNumber &b){
BigNumber c;
c.d[0]=max(a.d[0],b.d[0]);
int i,x=0;
for(i=1;i<=c.d[0];i++){
x=a.d[i]+b.d[i]+x;
c.d[i]=x%10000;
x/=10000;
}
while(x!=0){
c.d[++c.d[0]]=x%10000;
x/=10000;
}
return c;
}
BigNumber operator - (const BigNumber &a,const BigNumber &b){
BigNumber c;
c.d[0]=a.d[0];
int i,x=0;
for(i=1;i<=c.d[0];i++){
x=10000+a.d[i]-b.d[i]+x;
c.d[i]=x%10000;
x=x/10000-1;
}
while((c.d[0]>1)&&(c.d[c.d[0]]==0)){
c.d[0]--;
}
return c;
}
ll n,k;
BigNumber cal(int u)
{
BigNumber s1("1");
BigNumber s2("0");
dp[0][0]=s1;
dp[0][1]=s2;
for(ll i=1;i<=n;i++){
BigNumber sum=dp[i-1][0]+dp[i-1][1];
dp[i][1]=sum;
if(i<=u){
dp[i][0]=sum;
}else if(i==u+1){
dp[i][0]=sum-s1;
}else{
dp[i][0]=sum-dp[i-u-1][1];
}
}
return dp[n][0]+dp[n][1];
}
int main()
{
while(scanf("%lld%lld",&n,&k)!=EOF){
BigNumber ans=cal(n)-cal(k-1);
cout<<ans.toString()<<endl;
}
return 0;
}