[数位dp] upcoj 2223 A-Number and B-Number

题意:

A数列为,包含7或者能被7整除的数从小到大构成。

{a[1]=7,a[2]=14,a[3]=17,a[4]=21,a[5]=27,a[6]=28,a[7]=35,a[8]=37,a[9]=42,a[10]=47};

B数列为,是A数列里的数,但不包含第a[i]个A数列里的数列。

也就是B数列要去掉 a[7],a[14],a[17]这些要去掉。

{b[1]=7,b[2]=14,b[3]=17,b[4]=21,b[5]=27,b[6]=28,b[7]=37,b[8]=42,b[9]=47,b[10]=49};

现在给N,求第N个B数列里的数。

思路:

首先值得肯定的是,我们必须知道A数列,所以数位dp关于A数列。这个都很简单。

dp[i][j][k] 第i位,余数是j,k 代表是否含有了7.

然后就看第N个B数列的数,实际是第几个A数列的数。

我们假设是第N个B 数列的数,是第X个A数列的数。

那么满足N=X-solve(X)   solve(X) 代表1~X中有几个A数列的数。

会发现X-solve(X) 随着X的增大而增大。

所以二分出最小满足X-solve(X)=N 的X。

接着再一个二分求第X个A数列的数是多少就可以了~

最后就是需要注意,题目要求范围是2^63-1,所以开成 unsigned long long。

代码:

#include"stdio.h"
#include"algorithm"
#include"string.h"
#include"map"
#include"iostream"
#include"queue"
#include"string"
#define ll unsigned long long
using namespace std;
ll dp[22][8][2];
int num[22];
ll dfs(int site,int s,int o,int f)
{
    if(site==0)
    {
        if(o==1) return 1;
        if(s==0) return 1;
        return 0;
    }
    if(!f && dp[site][s][o]!=-1) return dp[site][s][o];
    ll ans=0;
    int len=f?num[site]:9;
    for(int i=0; i<=len; i++)
    {
        if(o==1) ans+=dfs(site-1,(s*10+i)%7,1,f&&i==len);
        else
        {
            if(i==7) ans+=dfs(site-1,(s*10+i)%7,1,f&&i==len);
            else ans+=dfs(site-1,(s*10+i)%7,0,f&&i==len);
        }
    }
    if(!f) dp[site][s][o]=ans;
    return ans;
}
ll solve(ll x)
{
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%10;
        x/=10;
    }
    return dfs(cnt,0,0,1)-1;
}
int main()
{
    ll n;
    memset(dp,-1,sizeof(dp));
    while(scanf("%llu",&n)!=-1)
    {
        ll l=1,r=(1LL<<63)-1,mid,kx;
        while(l<=r)
        {
            mid=(l+r)/2;
            ll tep=mid-solve(mid);
            if(tep>=n)
            {
                kx=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        ll ans;
        l=1,r=(1LL<<63)-1;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(solve(mid)>=kx)
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%llu\n",ans);
    }
    return 0;
}
时间: 2024-11-19 12:37:42

[数位dp] upcoj 2223 A-Number and B-Number的相关文章

hdu 5898 odd-even number 数位DP

odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 716    Accepted Submission(s): 385 Problem Description For a number,if the length of continuous odd digits is even and the length

Hdu3079Balanced Number数位dp

枚举支点,然后就搞,记录之前的点的力矩和. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <s

HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)

beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 801    Accepted Submission(s): 518 Problem Description Let A=∑ni=1ai?10n?i(1≤ai≤9)(n is the number of A's digits). We call A as "

hdu 5787 K-wolf Number 数位dp

数位DP 神模板 详解 为了方便自己参看,我把代码复制过来吧 // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位) // status = 要达到的状态,如果为1则可以认为找到了答案,到时候用来返回, // 给计数器+1. // limit = 是否受限,也即当前处理这位能否随便取值.如567,当前处理6这位, // 如果前面取的是4,则当前这位可以取0-9.如果前面取的5,那么当前 // 这位就不能随便取,不然会超出这个数的范围,所以如果前面取

codeforces Hill Number 数位dp

http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits:  200000 KB 64-bit interger IO format:  %lld   Java class name:  Main Description A Hill Number is a number whose digits possibly rise and then possibl

Balanced Number (数位dp)

Balanced Number Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box wit

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>

hdu3709---Balanced Number(数位dp)

Problem Description A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the nu

hdu 3709 Balanced Number (数位dp)

Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1871    Accepted Submission(s): 836 Problem Description A balanced number is a non-negative integer that can be balanced if a pi