• Codeforces Round #235 (Div. 2) D. Roman and Numbers 状压dp+数位dp


    题目链接:

    http://codeforces.com/problemset/problem/401/D

    D. Roman and Numbers

    time limit per test4 seconds
    memory limit per test512 megabytes
    #### 问题描述 > Roman is a young mathematician, very famous in Uzhland. Unfortunately, Sereja doesn't think so. To make Sereja change his mind, Roman is ready to solve any mathematical problem. After some thought, Sereja asked Roma to find, how many numbers are close to number n, modulo m. > > Number x is considered close to number n modulo m, if: > > it can be obtained by rearranging the digits of number n, > it doesn't have any leading zeroes, > the remainder after dividing number x by m equals 0. > Roman is a good mathematician, but the number of such numbers is too huge for him. So he asks you to help him. #### 输入 > The first line contains two integers: n (1 ≤ n < 1018) and m (1 ≤ m ≤ 100). #### 输出 > In a single line print a single integer — the number of numbers close to number n modulo m. ####样例输入 > 104 2

    样例输出

    3

    题意

    给你n和m,你可以对n的数位进行重排得到新的数,统计所有得到的数中能被m整除的有多少个。

    题解

    重排所有情况为len!个,len<=18我们可以考虑状压来做,然后处理下%m的余数就可以了。
    dp[i][j]表示状态为i,%m==j的所有情况。
    最后注意下前导零和去重就可以了。

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef __int64 LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    LL dp[1<<19][101];
    
    int main() {
        LL x; int m;
        scf("%I64d%d",&x,&m);
    
        int arr[22],n=0;
        while(x){ arr[n++]=x%10; x/=10; }
    
        clr(dp,0);
        dp[0][0]=1;
        bool vis[11];
        rep(i,1,(1<<n)){
            clr(vis,0);
            rep(j,0,n) if(i&(1<<j)){
                ///去除前导零
                if(arr[j]==0&&((i^(1<<j))==0)) continue;
                ///vis用来去重的,相同的数字谁排最后都一样,算一次就够了。
                if(vis[arr[j]]) continue;
                vis[arr[j]]=1;
                rep(k,0,m){
                    dp[i][(k*10+arr[j])%m]+=dp[i^(1<<j)][k];
                }
            }
        }
    
        prf("%I64d
    ",dp[(1<<n)-1][0]);
    
        return 0;
    }
    
    //end-----------------------------------------------------------------------
    

    Notes

    codeforces的空间限制是512MB!!!,int能开到10^8,long long 能开到5e7。

  • 相关阅读:
    ($children,$refs,$parent)的使用
    watch监听变化
    vue组件间通信六种方式(完整版)
    CSS水平垂直居中常见方法总结2
    CSS水平垂直居中常见方法总结
    Uncaught SyntaxError: Unexpected identifier 报错 import Vue from 'vue';
    前端跳槽面试必备
    防止重复发送Ajax请求问题
    JQuery中的$().each 以及 $.each的区别
    数组中的forEach和map的区别
  • 原文地址:https://www.cnblogs.com/fenice/p/5889085.html
Copyright © 2020-2023  润新知