[数位dp+二分] fzu 1074 Nancy's Birthday

题意:给m,n,问含有m个0的第k个数,是几位数,并且最高位是多少。

思路:和普通数位dp一样,加上个二分。

然后就是注意一下,极限值测试下能否算出来,这题极限值很大!

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
//2014年9月24日17:07:38
__int64 dp[22][22][11];
int num[22];
__int64 dfs(int site,int n,int m,int zero,int f)
{
    if(site==0)
    {
        if(zero) return 0;
        return n==m?1:0;
    }
    if(!f&&!zero&&~dp[site][n][m]) return dp[site][n][m];
    int len=f?num[site]:9;
    __int64 ans=0;
    for(int i=0; i<=len; i++)
    {
        if(zero) ans+=dfs(site-1,n,m,zero&&i==0,f&&i==len);
        else
        {
            if(i==0) ans+=dfs(site-1,n+1,m,zero&&i==0,f&&i==len);
            else ans+=dfs(site-1,n,m,zero&&i==0,f&&i==len);
        }
    }
    if(!f&&!zero) dp[site][n][m]=ans;
    return ans;
}
__int64 solve(__int64 x,int m)
{
    if(x<0) return 0;
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%10;
        x/=10;
    }
    return dfs(cnt,0,m,1,1);
}

int main()
{
    int t;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        __int64 k;
        int m;
        scanf("%d%I64d",&m,&k);
        __int64 l=1,r=9000000000000000000LL,mid,ans;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(solve(mid,m)>=k)
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        __int64 len,tt=1,n;
        len=(__int64)log10(ans*1.0)+1;
        n=len-1;
        while(n--) tt*=10;
        printf("%I64d %I64d\n",len,ans/tt);
        //printf("%I64d\n",ans);
    }
    return 0;
}
//2014年9月24日18:07:25

[数位dp+二分] fzu 1074 Nancy's Birthday

时间: 2024-10-10 06:55:27

[数位dp+二分] fzu 1074 Nancy's Birthday的相关文章

poj3208 Apocalypse Someday 数位dp+二分 求第K(K &lt;= 5*107)个有连续3个6的数。

/** 题目:poj3208 Apocalypse Someday 链接:http://poj.org/problem?id=3208 题意:求第K(K <= 5*107)个有连续3个6的数. 思路:数位dp+二分. dp[i][j]表示长度为i,前缀状态为j时含有的个数. j=0表示含有前导0: j=1表示前缀连续1个6 j=2表示前缀连续2个6 j=3表示前缀连续3个6 j=4表示前缀不是6: */ //#include<bits/stdc++.h> #include<cstr

hihocoder #1301 : 筑地市场 数位dp+二分

题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostream> #include<cstring> #include<cstdio> using namespace std; typedef long long LL; const LL INFLL = 0x3f3f3f3f3f3f3f3fLL; //dp[x][0]表示高位还没有出

[数位dp+二分] zoj Generalized Palindromic Number

题意: 找一个小于N的最大的且符合题意的数. 题意的数为,通过缩减后是回文的数,所谓的缩减就是相同连续的数看做一个数,如"155451111"其实就是"15451"是符合题意的数. 思路: 通过数位dp,然后二分求解. dp[i][j][k]代表第i位,已经放了j个数,最后长度是k的缩减回文数有几个. 然后需要一个ok[]数组代表放的数是什么,如果连续放相同的数就等于没放数. 遍历所有的长度就可以得到结果了. 其实不难发现,这种回文数一定是奇数位的. 代码: #in

[uva 1350]数位dp+二分

题目链接:https://vjudge.net/problem/38405 #include<bits/stdc++.h> using namespace std; long long dp[64][2]; int b[64]; long long dfs(int pos,int preok,int pre1) { if (pos==-1) return 1; if (preok && dp[pos][pre1]!=-1) return dp[pos][pre1]; int u

HDU 3943 K-th Nya Number(数位dp+二分)

Problem Description Arcueid likes nya number very much. A nya number is the number which has exactly X fours and Y sevens(If X=2 and Y=3 , 172441277 and 47770142 are nya numbers.But 14777 is not a nya number ,because it has only 1 four). Now, Arcueid

ACM学习历程—HDU5587 Array(数学 &amp;&amp; 二分 &amp;&amp; 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后从0到末尾,每一个都加上1. 例如:a0, a1, a2 => a0, a1, a2, 1, a0+1, a1+1, a2+1 题解中是这么说的:“ 其实Ai为i二进制中1的个数.每次变化A{k+2^i}=A{k}+1,(k<2^?i??)不产生进位,二进制1的个数加1.然后数位dp统计前m个数二

fzu 2109 Mountain Number 数位DP

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2109 题意: 如果一个>0的整数x,满足a[2*i+1] >= a[2*i]和a[2*i+2],则这个数为Mountain Number. 给出L, R,求区间[L, R]有多少个Mountain Number. 思路: 数位DP,判断当前是偶数位还是奇数位(从0开始),如果是偶数位,那么它要比前一个数的值小, 如果是奇数位,那么它要比前一个数的值大. 1 #include <iostream>

POJ 3208 Apocalypse Someday 二分答案+数位DP

这题应该是POJ最强大的一道数位DP了吧 正解是AC自动机 不会 还是写数位DP吧 题目大意:我们令含有666的数字为不吉利数字,则可以得到一个递增数列: {an}=666,1666,2666,3666,4666,5666,6660,6661,.... 给定n,求an 首先我们把这个问题转化成另一个问题:给定n,求1~n中有多少个数含有666 解决了这个问题,把原问题二分答案即可 首先预处理f数组,令 f[i][0]表示i位数中首位不为6且不含666的数的数量 f[i][1]表示i位数中首位连续

Codeforces Round #460 (Div. 2) B Perfect Number(二分+数位dp)

题目传送门 B. Perfect Number time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output We consider a positive integer perfect, if and only if the sum of its digits is exactly 1010. Given a positive integ