• 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。

  • 相关阅读:
    SQL 连接
    nvl() 数值替换函数 oracle使用
    Oracle 中sql语句中的取前n条数据
    设置序列
    Oracle创建用户 创建表空间 分配权限
    oracle11 刚刚安装后提示invalid username password logon denied
    关于index 索引
    事物
    数据库 oracle 设计三范式
    TXT编写程序-编译-执行流程
  • 原文地址:https://www.cnblogs.com/fenice/p/5889085.html
Copyright © 2020-2023  润新知