CodeForces 401D Roman and Numbers【数位dp+状态压缩】
来源:互联网 发布:网络咨询工作怎么样 编辑:程序博客网 时间:2024/05/21 23:49
source:
AnnouncementTutorial
题意:给你数n和m,求n的各位重排后有多少个满足膜m==0?
思路:由于n的范围最大可以到18位,故不能暴力枚举(会超时),那么思路就放在了带记忆化的枚举上,数位dp。重点在于如何记忆化,比如现在枚举到了第pos位,然后还需要剩下待定的各位和膜m为mmod,在什么情况下就能直接返回已知结果?当然是当待定的各位还有哪些选择和mmod都确定时结果便确定了:
这便是dp数组:dp[状态(还有那些数待安排)][mmod]
注:此处dp数组并没有pos这一维度,原因在于状态中就已经包含pos此维度了。
而下一个问题是如何表示状态——n的各位中待安排的数,这里就可以用到状态压缩的方式,将状态设成二进制串,每个二进制位对应n的数位上的数,取过就为0,待取就为1。
如此这般,要求的最终结果便是dp[111...1][0] 其中状态是strlen(n)个1
代码如下:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int con[10],a[20];long long dp[(1<<18)+2][105],dec[18];int m,len;long long dfs(int pos,int sta,int mmod,int lead){ int tem[20]; if(pos==-1) { if(sta!=0) printf("%d error!\n",sta); if(mmod==0) return 1; else return 0; } if(!lead && dp[sta][mmod]!=-1) return dp[sta][mmod]; long long ans=0; memset(tem,0,sizeof(tem)); //避免重复 for(int i=0;i<=len;i++) if(sta&(1<<i)) { if(lead && a[i]==0) continue; if(tem[a[i]]) continue; //若此位以试探过a[i],则跳过(目的是去重) tem[a[i]]=1; ans+=dfs(pos-1,sta-(1<<i),(mmod-dec[pos]*a[i]%m)%m,0); } if(!lead) dp[sta][mmod]=ans; return ans;}long long stat(long long x){ memset(con,0,sizeof(con)); int i=0; while(x>0) { int tem=x%10; con[tem]++; a[i++]=tem; x/=10; } len=i-1; return dfs(len,(1<<i)-1,0,1);}int main(){ long long n; scanf("%lld%d",&n,&m); memset(dp,-1,sizeof(dp)); dec[0]=1; for(int i=1;i<18;i++) dec[i]=dec[i-1]*10; printf("%lld\n",stat(n)); return 0;}
阅读全文
0 0
- CodeForces 401D Roman and Numbers【数位dp+状态压缩】
- Codeforce 401D Roman and Numbers[数位DP+状态压缩]
- Codeforces Round #235 (Div. 2) D. Roman and Numbers (数位dp、状态压缩)
- [数位dp] Codeforces 401D Roman and Numbers
- codeforces 401D Roman and Numbers (数位dp)
- codeforces 401D D. Roman and Numbers(状态压缩dp+数论)
- codeforces 401D Roman and Numbers(状态压缩)
- Codeforces Round #235 (Div. 2) D. Roman and Numbers(状态压缩DP)
- [Codefoces 401D]Roman and Numbers 数位dp
- cf 401D. Roman and Numbers 数位dp,状压
- Codeforces 401D Roman and Numbers【状压dp】
- Codeforces 401D Roman and Numbers 状压DP
- Codeforces Round #235 (Div. 2) / 410D Roman and Numbers (带有整除性质的数位DP)
- Codeforces Round #235 (Div. 2) D. Roman and Numbers 解题报告(状态压缩)
- Codeforces Round #235 (Div. 2) D Roman and Numbers(状态DP)
- CodeForces 401D Roman and Numbers
- codeforces 401D Roman and Numbers
- cf235,D Roman and Numbers(状态压缩dp)引发对dp中几种状态类型的思考
- Mysql数据库、数据表、数据的基本操作
- POJ 1258 Agri-Net(最小生成树) && POJ 2377 Bad Cowtractors(最大生成树)
- 代码重构点
- C#委托的介绍(delegate、Action、Func、predicate)
- opencv学习——视频读取、处理、保存
- CodeForces 401D Roman and Numbers【数位dp+状态压缩】
- 句柄是什么
- bzoj 2741: 【FOTILE模拟赛】L
- 正则化与数据先验分布的关系
- Maven详解
- python 和汽车软件开发
- JavaScript实现H5游戏断线自动重连的技术
- CentOS 7 源码安装 mysql5.7.12 完整教程
- 福建历年-油滴扩展