• codeforces 401D Roman and Numbers


    题目简述:

    给定n和m,求把n的各位数字重排后有多少数能被m整除(禁止有前导0的数)

    n (1 ≤ n < 1018) and m (1 ≤ m ≤ 100).

    本来是打算做一道数位DP的 然后看到了这题 也往数位DP上想 结果……

    ------------------------------------------------------------------------------------------------------

    还是来说正解吧 正解是状压DP

    我们可以用$f[i][j]$表示已用的数字集合为$i$,对$m$求余为$j$的方案数

    每次往一个较小的集合所构成的数末尾添加一个数字得到一个较大的集合(这样前导0更方便处理)

    然后注意不同位上的相同数字是等价的 于是最后还要除一下所有数字出现次数的阶乘

    #include <bits/stdc++.h>
    using namespace std;
    long long f[1<<18][100];
    int num[18],pos[1<<18],cnt[10];
    long long n;
    int m,top;
    int main()
    {
        scanf("%lld%d",&n,&m);
        int tmp=1;
        while(n)
        {
            cnt[n%10]++;
            pos[tmp]=n%10;
            num[top++]=n%10;
            n/=10;
            tmp<<=1;
        }
        for(int i=1;i<(1<<top);++i)
            if(i==(i&-i))
                f[i][pos[i]%m]=(pos[i]!=0);
            else
            {
                for(int j=0;j<top;++j)
                    if(i&(1<<j))
                        for(int k=0;k<m;++k)
                            f[i][(k*10+num[j])%m]+=f[i^(1<<j)][k];
            }
        long long ans=f[(1<<top)-1][0];
        for(int i=0;i<=9;++i)
            for(int j=1;j<=cnt[i];++j)
                ans/=j;
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    优化总结文章链接
    帧同步、状态同步
    ecs
    AStarPathFinding
    unity 热更方案对比
    C#数据类型
    JavaScript基础
    CSS中margin和padding的区别
    css选择器
    hadoop中使用shell判断HDFS文件是否存在
  • 原文地址:https://www.cnblogs.com/sagitta/p/4748542.html
Copyright © 2020-2023  润新知