传送门
https://acm.hdu.edu.cn/showproblem.php?pid=4352
①用state记录状压后的这个数转换的字符串数组的情况,通过bitset来转换状态
②剩下的就是数位dp的板子了
debug了一个小时 没找到问题
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll int maxn = 120;
const ll int N = 1e5+10;
#define bug(x) cout<<#x<<"=="<<x<<endl;
int dp[30][3000][30] = { 0 };
int a[30] = { 0 };
int pos = 0;
int k;
inline bool check(int x)
{
bitset<15> bits = x;
return bits.count()==k;
///数组里面有多少个1
}
inline int get_next(int state,int now)
{
bitset<15> bits=state;
int i=now;
for(; i<=9; i++)
{
if(bits[i]==1)
{
break;
}
}
if(i!=10)
{
bits[i] = 0;
}
bits[now]=1;
///修改最长序列的末尾值
int ans=bits.to_ulong();
///讲二进制的数组转换成unsigned long的整数型
return ans;
}
int dfs(int pos,int state,bool lead,bool limit)
{
if(!pos)
{
return check(state);
}
if( (!limit&&!lead) &&dp[pos][state][k]!=-1)
{
return dp[pos][state][k];
}
int up=9;
if(limit)
{
up=a[pos];
}
int ans = 0;
for(int i=0; i<=up; i++)
{
if(lead&& i==0 )
{
ans += dfs(pos-1,state,lead&& i==0,limit&&i==a[pos]);
}
else
{
int next_state=get_next(state,i);
ans += dfs(pos-1,next_state,lead&& i==0,limit&&i==a[pos]);
}
}
if(!limit&&!lead)
{
dp[pos][state][k] = ans;
}
return ans;
}
int slove(ll x)
{
if(x==0)return 0;
pos = 0;
while(x)
{
pos++;
a[pos] = x%10;
x /= 10;
}
int ans=dfs(pos,0,true,true);
if(ans==0)
return 0;
return ans;
}
signed main()
{
ll l,r;
int T_T;
scanf("%d",&T_T);
memset(dp,-1,sizeof(dp));
int tot=0;
while(T_T--)
{
tot++;
cin>>l>>r>>k;
printf("Case #%d: ",tot);
cout<<slove(r)-slove(l-1)<<'\n';
}
}