博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3208-Apocalypse Someday(数位dp)
阅读量:5320 次
发布时间:2019-06-14

本文共 1234 字,大约阅读时间需要 4 分钟。

题意:给定n,输出第n大包含666的数字。

分析:dp[i][j][k][l]表示 长度为i,当前位是否是6,前一位是否6,是否已经包含666,表示的数量,再用二分找出第n大的这样的数字。

#include #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef pair
PII;typedef long long ll;#define lson l,m,rt<<1#define pi acos(-1.0)#define rson m+1,r,rt<<11#define All 1,N,1#define read freopen("in.txt", "r", stdin)const ll INFll =0xfffffffffLL;const int INF= 0x7ffffff;const int mod =1000000007;ll dp[64][2][2][2],n;int bit[64];ll dfs(int i,int j,int k,int l,int e){ if(i==0) return l; if(!e&&dp[i][j][k][l]!=-1) return dp[i][j][k][l]; int u=e?bit[i]:9; ll num=0; for(int v=0;v<=u;++v){ if(l==1) num+=dfs(i-1,v==6,j,1,(e&&v==u)); else num+=dfs(i-1,v==6,j,j&&k&&v==6,(e&&v==u)); } return e?num:dp[i][j][k][l]=num;}ll getnum(ll x){ int len=0; while(x){ bit[++len]=x%10; x/=10; } return dfs(len,0,0,0,1);}int main(){ memset(dp,-1,sizeof(dp)); int t; scanf("%d",&t); ll n; while(t--){ scanf("%I64d",&n); ll l=1,r=INFll,mid; while(l<=r){ mid=(l+r)>>1; if(getnum(mid)

 

转载于:https://www.cnblogs.com/zsf123/p/4679260.html

你可能感兴趣的文章
Centos7.2正常启动关闭CDH5.16.1
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>
Java 实践:生产者与消费者
查看>>
[转]IOCP--Socket IO模型终结篇
查看>>
js 获取视频的第一帧
查看>>
各种正则验证
查看>>
观察者模式(Observer)
查看>>
python中numpy.r_和numpy.c_
查看>>
egret3D与2D混合开发,画布尺寸不一致的问题
查看>>
freebsd 实现 tab 命令 补全 命令 提示
查看>>
struts1和struts2的区别
查看>>
函数之匿名函数
查看>>
shell习题第16题:查用户
查看>>
实验4 [bx]和loop的使用
查看>>
Redis常用命令
查看>>
2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)
查看>>