zoukankan      html  css  js  c++  java
  • CF401D 【Roman and Numbers】

    题意
    将n(n<=10^18)的各位数字重新排列(不允许有前导零)  求  可以构造几个mod m等于0的数字
    解法
    状压
    f[S][k] 表示选用的位数集合为S,mod m 为k的方案数
    注意不能有前导0
    但是这样做是有缺陷的
    状压本质上是将每个数按下标强行看作不同的数
    因此有重复统计的情况
    比如n=11,方案只有1种,状压会有2种
    根据多重集合的排列,如果一个数字出现了cnt次,那么答案会被重复计算cnt!次,答案需要除以cnt!
    上代码

    #include<iostream>
    #include<cstring>
    #define int long long
    using namespace std;
    const int maxs=(1<<18)+10,maxm=110;
    int w[20],cnt=-1,m,n,f[maxs][maxm];
    bool vis[10];
    signed main()
    {
        for(cin>>n>>m;n;n/=10)
            w[++cnt]=n%10;
        f[0][0]=1;
        for(int s=1;s<1<<cnt+1;s++)
        {
            memset(vis,0,sizeof(vis));
            for(int i=0;i<=cnt;i++)
            {
                if(s==(1<<i)&&!w[i])
                    break;
                if(!(s&(1<<i))||vis[w[i]])
                    continue;
                vis[w[i]]=1;
                for(int j=0;j<m;j++)
                    f[s][(j*10+w[i])%m]=f[s][(j*10+w[i])%m]+f[s^(1<<i)][j];
            }
        }
        cout<<f[(1<<cnt+1)-1][0]<<endl;
        return 0;
    }
  • 相关阅读:
    数据库内外连接以及自然连接
    Mybatis的一级二级缓存
    彻底弄懂CAS单点登录
    Tomcat部署项目的方式
    redis集群脑裂以及解决方案
    AOP分析--代理方式的选择
    线程池
    数据结构--结构体
    Python程序--选择判断
    C语言--密码问题
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/9021715.html
Copyright © 2011-2022 走看看