排列

来源:互联网 发布:车辆调度系统 源码 编辑:程序博客网 时间:2024/05/17 04:54
题意:给出一个小于等于10位的数,再给一个mod数,
        这个字符串的数可以任意换,求出其能被mod求余为0的排列个数。

思路:用dp[i][j]代表i是一个二进制数,每一位代表其取与不取。
         j是代表取数的状态为i 时的余数。

         转移方程:dp[i][j] += dp[i-(1<<k)][(j*10+a[k])%d]




#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define N 1001long  dp[1<<10][N];int n,m;int vis[1<<10][N];char a[11];long  get(int i,int j){//cout<<i<<' '<<j<<endl;if (vis[i][j])return dp[i][j];dp[i][j]=0;int k;int cur;for (k=0;k<n;k++){if ((1<<k) & i)dp[i][j]+=get(i-(1<<k),(j*10+a[k]-'0')%m);}vis[i][j]=true;//cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;return dp[i][j];}int main(){freopen("in.txt","r",stdin);int i,j,k;int nc;cin>>nc;while (nc--){cin>>a>>m;n=strlen(a);memset(vis,false,sizeof(vis));vis[0][0]=true;dp[0][0]=1;long ans=get((1<<n)-1,0);int num[11];num[0]=1;for (i=1;i<11;i++)num[i]=num[i-1]*i;int cur[11];memset(cur,0,sizeof(cur));for (i=0;i<n;i++)cur[a[i]-'0']++;for (i=0;i<11;i++)ans/=num[cur[i]];cout<<ans<<endl;}return 0;}






原创粉丝点击