【POJ3208】传说中POJ最难的数位DP?(正解AC自动机,二解数位DP,吾异与之)
来源:互联网 发布:淘宝嘉年华报名要求 编辑:程序博客网 时间:2024/05/15 22:59
题意:
多组数据,每组求第n个包含‘666’的数(不能断开),如1:666,2:1666,14:6667。
题解:
AC自动机解法没去想,数位DP没学,这里有一种类似于数位DP,却又与数位DP不同,我称为数位树。
数位树:
将数n如线段树一样地拆分成多个小段,进行递归处理得出答案。
本题详(lue)解:
直接看每一位应该是什么数,然后n减去相应的数,使得在下一层转换为子问题“在开头有b个连续的6时,求第a个带‘666’的数”。就是如此简单,如此简单!!!!
代码来啦!
#include <cstdio>#include <cstring>#include <algorithm>#define N 20/*数的最大保证位数*/using namespace std;long long n;long long f0[N],f1[N],f2[N],f3[N];long long f10[N],f5[N],f6[4][N];/*注一:[N]处为位数注二:这里说的数不去首位0,即0066算4位数f0:首位不为6且不含‘666’的数的个数f1:首位 为6且不含‘666’的数的个数(第二位不为‘6’)f2:首位 为6且不含‘666’的数的个数(第二位 为‘6’)f3:含‘666’的数的个数f5:5开头的含‘666’的数的个数f6:1:开头含‘6’的数的个数2:开头含‘66’的数的个数3:含‘666’的数的个数f10:同f3*/long long power(long long x,long long p){long long ans=1;while(p>0){if(p&1)ans*=x;x*=x;p>>=1;}return ans;}void dfs(long long nn,long long nm)/*位数,已连续的6的个数*/{if(!nn)/*没有位了,结束!*/{printf("\n");return ;}long long i,j,k;if(nm>=3)/*剪枝(如果前面已经‘666’了,那么直接算数就好)*/{long long tens=1;n--;for(i=1;tens<=n;i++,tens*=10);for(;i<=nn;i++)printf("0");if(n)printf("%I64d",n);printf("\n");return ;}if(f5[nn]>=n)/*此位为0~5*/{printf("%I64d",(n-1)/f10[nn-1]);n=(n-1)%f10[nn-1]+1;dfs(nn-1,0);return ;}else if(f6[3-nm][nn]>=n)/*此位为6*/{printf("6");n-=f5[nn];dfs(nn-1,nm+1);return ;}else/*此位为7~9*/{n-=f6[3-nm][nn];printf("%I64d",(n-1)/f10[nn-1]+7);n=(n-1)%f10[nn-1]+1;dfs(nn-1,0);return ;}}void init()/*预处理*/{long long i;f0[0]=1;for(i=1;i<N;i++){f0[i]=(f0[i-1]+f1[i-1]+f2[i-1])*9;f1[i]=f0[i-1];f2[i]=f1[i-1];f3[i]=f3[i-1]*10+f2[i-1];}for(i=3;i<N;i++)/*i位数中含‘666’的数的个数*/{f10[i]=f3[i];f5[i]=6*f10[i-1];f6[3][i]=f10[i]-3*f10[i-1];f6[2][i-1]=f6[3][i]-f5[i]-3*f10[i-2];f6[1][i-2]=f6[2][i-1]-f5[i-1]-3*f10[i-3];}}int main(){long long i,g;scanf("%I64d",&g);init();while(g--){scanf("%I64d",&n);for(i=3;f10[i]<n;i++);dfs(i,0);}return 0;}
1 0
- 【POJ3208】传说中POJ最难的数位DP?(正解AC自动机,二解数位DP,吾异与之)
- 数位DP POJ3208 Apocalypse Someday
- poj 1625 AC自动机上的DP
- POJ 1625 Censored(AC自动机+dp)
- [POJ3208]Apocalypse Someday-二分-数位DP
- BUPT 652 Confusing Problem(AC自动机+数位DP)
- ZOJ3494 BCD Code (AC自动机+数位DP)
- ZOJ - 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code (AC自动机 + 数位DP)
- bzoj 3530: [Sdoi2014]数数 (AC自动机+数位DP)
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位dp)
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位DP)
- ZOJ 3494 BCD Code(数位dp+AC自动机)
- SMOJ 1981 豆腐(数位DP+AC自动机)
- bzoj3530 [Sdoi2014]数数(AC自动机+数位DP)
- CC FAVNUM (AC自动机+数位DP)
- 【AC自动机+数位DP】SDOI2014 数数
- HDU 4518 ac自动机+数位dp
- ios单例
- ZOJ-#3465 The Hive(字符串模拟)
- strcpy源码分析
- 暑期开发过程中的一些经验记录
- 如果刚装好的ORACLE,却无法访问数据库,则把LINSTENER删除试试
- 【POJ3208】传说中POJ最难的数位DP?(正解AC自动机,二解数位DP,吾异与之)
- luaAPI解析
- Internal Patent Idea Candidates
- CF 题目集锦 PART 7 #264 div 2 E
- 根据MySQL表数据导出INSERT INTO语句的方法
- 百度编辑器ueditor的使用
- C++ const小结
- 浅谈在Tomcat中监控JVM内存使用情况
- 递归的练习——使用递归算法利用欧几里得算法,得出最大公约数