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;
}

原文地址:https://www.cnblogs.com/ivanovcraft/p/9021715.html

时间: 2024-10-22 12:54:38

CF401D 【Roman and Numbers】的相关文章

【Add Two Numbers】

题目: You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 -&

leetcode 【 Add Two Numbers 】 python 实现

题目: You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 -&

【Roman To Integer】cpp

题目: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 代码: class Solution { public: int romanToInt(string s) { const int size = 7; std::map<char, int> symbol_value; char symbol_ori[size] = {'M

题解 CF817C 【Really Big Numbers】

题目链接:CF817C 前置算法 : 二分 我们先考虑如何得到答案,若最小满足\(x\)减去其各数位之和后大于\(s\) \(ans = n - x + 1\) 我们只要打个表就可以发现\(:\) 若\(x < y\)则\(|x| \leq |y|\) \((\)设\(|x|\)表示\(x\)减去其各数位之和\()\) 证明就不写了 说明答案是递增的, 那就用二分 我们二分出最小满足\(|x|\)大于\(s\) \(check\)函数就根据题意所写 如果找不到\(|x| \leq s\)就输出\

poj 3252 Round Numbers 【推导&#183;排列组合】

以sample为例子 [2,12]区间的RoundNumbers(简称RN)个数:Rn[2,12]=Rn[0,12]-Rn[0,1] 即:Rn[start,finish]=Rn[0,finish]-Rn[0,start-1] 所以关键是给定一个X,求出Rn[0,X] 现在假设X=10100100  这个X的二进制总共是8位,任何一个小于8位的二进制都小于X 第一部分,求出长度为[0,7]区间内的二进制是RoundNumber的个数  对于一个长度为Len的二进制(最高位为1),如何求出他的Rou

hdoj 1492 The number of divisors(约数) about Humble Numbers 【数论】【质因子分解 求和】

定理:一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的个数就是,(r1+1)*(r2+1)*...*(rk+1). 理解:为什么是加1之后再相乘,因为一个数的的因子数至少为1和他自身,但因为r1,r2..可以为0,所以因子的个数为(r1+1)... 拓展一下: 定理1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的

【leetcode 字符串处理】Compare Version Numbers

[leetcode 字符串处理]Compare Version Numbers @author:wepon @blog:http://blog.csdn.net/u012162613 1.题目 Compare two version numbers version1 and version1. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. You may assume

【题解】【数组】【Prime and composite numbers】【Codility】Flags

A non-empty zero-indexed array A consisting of N integers is given. A?peak?is an array element which is larger than its neighbours. More precisely, it is an index P such that 0 < P < N ? 1 and A[P ? 1] < A[P] > A[P + 1]. For example, the follo

【题解】【数组】【Prime and composite numbers】【Codility】Peaks

A non-empty zero-indexed array A consisting of N integers is given. A?peak?is an array element which is larger than its neighbors. More precisely, it is an index P such that 0 < P < N ? 1,? A[P ? 1] < A[P] and A[P] > A[P + 1]. For example, the