给定一个n,k,m,求一个n位的二进制数,由k段连续0或者1组成,然后每段不超过m个的方案数。没前导0.
问题转化一下就是,k个数字,每个数字取值为1-m,组成一个和为n的方法有多少种。
就是和lightoj 1145一样的问题啦。而且范围只有50,但是卧槽时限只有0.5s啊...前缀和优化走起..
我觉得这个题可以用数位DP做的
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mod 100000007
#define inf 0x3f3f3f3f
ll dp[55][55];
int main()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
int n,k,m;
scanf("%d %d %d",&n,&k,&m);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
ll sum;
for(int i=1;i<=k;i++)
{
sum=0;
for(int j=0;j<=n;j++)
{
dp[i][j]=sum;
if(j<m)
sum+=dp[i-1][j];
else
sum+=dp[i-1][j]-dp[i-1][j-m];
}
}
printf("Case %d: %lld\n",cas,dp[k][n]);
}
return 0;
}