继续做状压,多校比赛时没能出这道题,然后自己再做时发现很多人的博客里代码中都直接默认l>k令我好久没有理解,而且居然还能AC。。。这道题的数据可能弱了一点吧。。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <iomanip>
using namespace std;
const int maxn=1<<21;
const int mod=1e9+7;
int n,k,l,d,s;
long long ans;
long long dp[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&k,&l);
if(l>k)
{
d=l-k;//3 5 4 这组数据应该是54才对,结果别人66也能过,应该是没有k>l的数据
}
else
{
d=0;//不在[1,k]范围内的数字数目
}
l=min(l,k);//只需要考虑[1,k]
s=(1<<k)-1;//第i位代表i能否被取到
dp[0]=1;//初始为1
long long sum;
for(int i=0;i<n;i++)//n个数
{
for(int j=s;j>=0;j--)
{
sum=dp[j];
if(sum==0)//剪枝
{
continue;
}
for(int w=1;w<=l;w++)//枚举加上w后能取到的状态
{
long long temp;
temp=(1<<(w-1))|j|((j<<w)&s);
dp[temp]=(dp[temp]+sum)%mod;
}
dp[j]+=(sum*d%mod);//不在[1,k]内的情况
dp[j]%=mod;
}
}
ans=0;
for(int i=0;i<=s;i++)
{
if(i&(1<<(k-1)))//k能去到的情况全+
{
ans+=dp[i];
ans%=mod;
}
}
cout<<ans<<endl;
}
return 0;
}