题目:
好像是这方面的裸题。
整除k 要想转移需要记录下 达到模k所有余数 的方案数。
为了生成排列,状压记录当前已用了原数组中的哪些位置;
因为是无顺序地取用的,所以可以有顺序地放在目标数组中,即续在上一个数后面;所以 导致的余数 就是 之前余数*10+这个数。
另一种想法是有顺序取用、无顺序放置;即用了前 i 个数,状压记录放在了哪些位置上;新加入一个数的贡献是 之前余数+这个数*1ek。
感觉第一种比较方便?
循环的顺序需要注意!要把状压的状态 j 放在最外面,而不是当前位置 i 。
dp的初值需要想想。
对于值相等的一些数字,在排列中无区别,dp的时候却有区别地对待了。
只需要对于每一组,答案除去它们的排列数(即阶乘)即可。
#include#include #include using namespace std;int t,a[15],cnt,k,d[1030][1005],lm,ans,num[15];char ch;int kj[15]={ 1,1,2,6,24,120,720,5040,40320,362880,3628800};int main(){ scanf("%d",&t); while(t--) { cnt=0;ans=0; memset(d,0,sizeof d); memset(num,0,sizeof num); d[0][0]=1;///// scanf(" %c",&ch); while(ch>='0'&&ch<='9') { a[++cnt]=ch-'0'; num[a[cnt]]++; ch=getchar(); } lm=(1<