我是靠谱客的博主 复杂歌曲,最近开发中收集的这篇文章主要介绍codeforces401D Roman and Numbers(数位、状压dp),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目大意:给n和m,求有多少方案,使得重新排列n的数位后能整除m,不能有前导0

(n<01e18,m<0100)

思路:数位dp

从高位到低位进行dp,dp[s][k]表示当前集合s(现在选了那几个数)模m后的余数为k的方案数

时间复杂度O(18*(2^18))

核心转移方程,dp[now][(上次余数*10+a[i])%m] += dp[pre][上次余数]

不过这样算会算重复,比如n=111,可以从101,011,110转移过来,所以最后要除以num[i]! (i出现的次数,i从1到9)

因为要排除前导0的情况,我先算最高位的方案数,这样就把0的方案排除了,比如n=210,最高位我算2,1就好了

注意:我们并不关心集合(状态s)的每个1是第几位,我们只关心上个状态的方案数,比如now = 101,我们只要看001和100的方案数,加上的1就现在处理的a[j](默认放在末尾)

(感觉这样写好理解一点,看了网上代码a[i]==0时候要contine不是很理解QAQ)

(语文不好,表达有点混乱。。。)

#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
typedef long long ll;
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false)
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define pb push_back
#define int long long
const int N=3e5+10;
int n,m,k;
int num[10];
int dp[(1<<18)][105];
vector<int > v;
void solve()
{
    n = v.size();
    for(int i=0 ;i<v.size() ;i++)//先算第一位,避免算到前导0
    {
        if(v[i])//非0
        {
            dp[1<<i][v[i]%m]=1;
        }
    }
    for(int i=0 ;i<(1<<n) ;i++)//state
    {
        for(int j=0 ;j<v.size() ;j++)//枚举选哪个
        {
            if( i&(1<<j) )
            for(int k=0 ;k<m ;k++)
            {
                dp[i][(k*10+v[j])%m] += dp[i^(1<<j)][k];//转移后  - j = 转移前
            }
        }
    }
    _for(i,0,9)
    {
        _for(j,1,num[i])
        {
            dp[(1<<n)-1][0] /= j;
        }
    }
    cout<<dp[(1<<n)-1][0]<<endl;
}
signed main()
{
//    freopen("data.txt","r",stdin);
    cin>>n>>m;
    while( n )
    {
        v.pb(n%10);
        num[n%10]++;
        n /= 10;
    }
    solve();
}

最后

以上就是复杂歌曲为你收集整理的codeforces401D Roman and Numbers(数位、状压dp)的全部内容,希望文章能够帮你解决codeforces401D Roman and Numbers(数位、状压dp)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部