A,B,C水题,没啥好说的。
D:
dp[i][j]:现在用的数的状态为i,余数为j的数量
st[i]:使用数i,需要增加的状态
need[i]:使用数i最多可以增加到的状态。
pan[i]:状态i所在的区间。
dp[k+st[j]][(i*10+j)%m]+=dp[k][i];
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL __int64
LL dp[1<<18][101];
LL st[10];
LL pan[10];
LL num[11];
LL need[11];
int main()
{
LL n,m;
LL i,j,k,t;
while(~scanf("%I64d%I64d",&n,&m))
{
memset(num,0,sizeof(num));
memset(pan,0,sizeof(pan));
LL len=0;
while(n)
{
len++;
num[n%10]++;
n=n/10;
}
LL ls=0;
LL as=0;
for(i=0; i<=9; i++)
{
if(num[i]==0)continue;
LL li=0;
LL tt;
tt=num[i];
while(tt)
{
li++;
tt=tt/2;
}
tt=num[i];
st[i]=(1<<ls);
as=as+(tt<<ls);
need[i]=tt<<ls;
ls+=li;
pan[i]=((1<<ls)-1)-(st[i]-1);
}
dp[0][0]=1;
k=as;
for(k=0;k<=as;k++)
{
for(j=0;j<=9;j++)
{
if(k==0&&j==0)continue;
if((k&pan[j])>=need[j])continue;
for(i=0;i<m;i++)
{
dp[k+st[j]][(i*10+j)%m]+=dp[k][i];
}
}
}
LL sum=0;
sum=dp[as][0];
cout<<sum<<endl;
}
return 0;
}