题目链接:http://lx.lanqiao.cn/problem.page?gpid=T13
解题方案:dp,在分析问题的时候可以发现每次都要计算的重复子问题:i位数以数字j为首的有多少个。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define FOR(i,k,n) for(int i=k;i<n;i++)
#define FORR(i,k,n) for(int i=k;i<=n;i++)
#define scan(a) scanf("%d",&a)
#define scann(a,b) scanf("%d%d",&a,&b)
#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mst(a,n) memset(a,n,sizeof(a))
#define ll long long
#define N 105
#define mod 1000000007
#define INF 0x3f3f3f3f
const double eps=1e-8;
const double pi=acos(-1.0);
ll dp[N][N];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int k,l;
scann(k,l);
if(k==1)
{
printf("0\n");//之前输出了1,结果得了90分,1进制的话不是不管多少位全是0吗?百度了一下也没搞懂1进制。。
return 0;
}
for(int j=0;j<k;j++) dp[1][j]=1;//计算时以0为首位的也要算
for(int i=2;i<=l;i++)
{
for(int j=0;j<k;j++)//计算时以0为首位的也要算,因为在往后推的时候0可能为中间位或末尾位
{
for(int p=0;p<k;p++)
{
if(abs(p-j)!=1) dp[i][j]=(dp[i][j]+dp[i-1][p])%mod;
}
}
}
ll ans=0;
for(int p=1;p<k;p++)//最后求和的时候以0为首位的不算进去
ans=(ans+dp[l][p])%mod;
printf("%lld\n",ans);
return 0;
}