zoukankan      html  css  js  c++  java
  • BZOJ1072: [SCOI2007]排列perm

    BZOJ1072: [SCOI2007]排列perm

    Description

      给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。

    例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种。

    Input

      输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。

    s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

    Output

      每个数据仅一行,表示能被d整除的排列的个数。

    Sample Input

    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29

    Sample Output

    1
    3
    3628800
    90
    3
    6
    1398

    HINT

    在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。
    【限制】
    100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15


    题解Here!

    很明显,枚举每个数字是否被选即可。
    这个很明显是一个装状压$DP$对吧。

    设$dp[i][j]$表示选了几个数字,$mod d$的余数为$j$的方案数,$i$为选的数字状态的压缩。

    再用排列组合原理去重即可。

    具体可以看代码。

    记得多组数据要清空数组。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,d,S,ans;
    int num[15],f[15],A[15],B[1<<10],c[15],dp[(1<<10)+1][1010];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    int sum(int x){
    	int y=0;
    	while(x){
    		if(x&1)y++;
    		x>>=1;
    	}
    	return y;
    }
    void make(){
    	f[0]=A[0]=1;
    	for(int i=1;i<=10;i++){
    		f[i]=f[i-1]*i;
    		A[i]=A[i-1]*10;
    	}
    	for(int i=0;i<(1<<10);i++)B[i]=sum(i);
    }
    void work(){
    	for(int i=1;i<S;i++)
    	for(int j=0;j<n;j++)
    	if((1<<j)&i){
    		int k=A[B[i]-1]%d*num[j+1]%d;
    		for(int l=0;l<d;l++)dp[i][(l+k)%d]+=dp[i^(1<<j)][l];
    	}
    	ans=dp[(1<<n)-1][0];
    	for(int i=1;i<=n;i++)c[num[i]]++;
    	for(int i=0;i<=9;i++)ans/=f[c[i]];
    	printf("%d
    ",ans);
    }
    void init(){
    	char ch[15];
    	scanf("%s",ch);d=read();
    	n=strlen(ch);
    	for(int i=0;i<n;i++)num[i+1]=ch[i]-'0';
    	memset(dp,0,sizeof(dp));
    	memset(c,0,sizeof(c));
    	S=1<<n;
    	dp[0][0]=1;
    }
    int main(){
    	make();
    	int t=read();
    	while(t--){
    		init();
    		work();
    	}
    	return 0;
    }
    
  • 相关阅读:
    设置GridView、DataGrid 以提供thead、tbody等标签
    SqlCommandBuilder 可批量新增与修改数据
    js中的截流
    react代码分离方案
    redux在react中的使用
    react 生命周期
    react 函数bind(this)的三种方式
    react 三种组件定义方式
    linux系统下nginx安装目录和nginx.conf配置文件目录
    react component lifecycle
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9937108.html
Copyright © 2011-2022 走看看