$Poj3208$ 启示录 数位统计$DP$
2024-09-06 16:53:26
Description
Sol
这题长得就比较像数位$DP$叭.
所以先用$DP$进行预处理,再基于拼凑思想,通过"试填法"求出最终的答案.
设$F[i][3]$表示由$i$位数字构成的魔鬼数有多少个,$F[i][j](0<=j<=2)$表示由$i$位数字组成的,开头有$j$个$6$的非魔鬼数有多少个.注意,在计算$F[i][j]$时允许前导$0$的存在
$F[i][0]=9*(F[i-1][0]+F[i-1][1]+F[i-1][2])$
$F[i][1]=F[i-1][0]$
$F[i][2]=F[i-1][1]$
$F[i][3]=F[i-1][2]+10*F[i-1][3]$
预处理完成之后,我们先通过$F[i][3]$确定第$X$小魔鬼数的位数,然后从左到右进行试填,试填的数从小到大枚举
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#define Rg register
#define il inline
#define db double
#define ll long long
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i--)
using namespace std;
il int read()
{
int x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
int T,n,d,k;
ll f[][];
il void init()
{
f[][]=;
go(i,,)
{
f[i][]=*(f[i-][]+f[i-][]+f[i-][]);
f[i][]=f[i-][];
f[i][]=f[i-][];
f[i][]=f[i-][]+*f[i-][];
}
}
int main()
{
init();T=read();
while(T--)
{
n=read();d=;k=;
while(f[d][]<n)d++;
yes(i,d,)
{
go(j,,)
{
//求若第i位为j,那么剩下i-1位有多少种填法能使这个数成为魔鬼数
ll ct=f[i-][];
if(j== || k>=)
go(t,max(,-k-(j==)),)ct+=f[i-][t];
if(ct<n)n-=ct;//应该填一个更大的数
else //就填j
{
if(j==)k++;else if(k<)k=;
printf("%d",j);break;
}
}
}
printf("\n");
}
return ;
}
最新文章
- python优先队列,队列和栈
- what do i get for?
- 【leetcode】Unique Binary Search Trees II
- 七天学会NodeJS (原生NodeJS 学习资料 来自淘宝技术团队)
- C#开发COM组件供其他开发环境或工具调用介绍(转)
- Parse--Saving Images(翻译)
- LeetCode17 Letter Combinations of a Phone Number
- 如何使用Xcode6 调试UI,Reveal
- 通过Shell脚本读取properties文件中的参数时遇到\r换行符的问题
- JavaScript看书笔记01
- 什么是NAS.什么是黑白群晖?(转)
- 安卓TV开发(七) 移动智能终端多媒体之在线解析网页视频源
- Sublime Text 3安装SFTP插件
- 四、蛋炒饭(Egg fried rice)
- Jquery制作小星星(常用于评价)
- 从前端角度看ajax如何保护接口的安全性
- C# 中颜色和名称样式对照表
- bzoj千题计划302:bzoj3160: 万径人踪灭
- Intent的作用和表现形式简单介绍
- 基于 Python 和 Pandas 的数据分析(7) --- Pickling