码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3271-SNIBB(数位dp)

时间:2015-07-27 20:44:11      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

题意:给一个数q,

q=1时求给定区间,给定进制,各数位和等于m的数字的个数

q=2时求给定区间,给定进制,各数位和等于m的数字中的第k大的数字

分析:dp[i][sum][j],表示长度为i当前数位和是sum,进制是j的个数,q=2时用二分求出k大数

题意给的区间[x,y],x不一定小于y,给定区间没k大数,则输出 Could not find the Number!

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> 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 = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
ll dp[50][500][65],x,y,k;
int b,m,bit[50];
ll dfs(int i,int s,int j,int e){
    if(i==0)return (s==m);
    if(!e&&dp[i][s][j]!=-1)return dp[i][s][j];
    int u=e?bit[i]:b-1;
    ll num=0;
    for(int v=0;v<=u;++v){
        num+=dfs(i-1,s+v,j,e&&(v==u));
    }
    return e?num:dp[i][s][j]=num;
}
ll solve1(ll a){
    int len=0;
    if(a<0)return 0;
    while(a){
        bit[++len]=a%b;
        a/=b;
    }
    return dfs(len,0,b,1);
}
ll solve2(){
    ll l=x,r=y;
    ll num=solve1(x-1);
    if(solve1(y)-num<k)return -1;
    while(l<=r){
        ll mid=(l+r)>>1;
        if(solve1(mid)-num<k)l=mid+1;
        else r=mid-1;
    }
    return l;
}
int main()
{
    int q,cas=0;
    while(~scanf("%d",&q)){
        memset(dp,-1,sizeof(dp));
        printf("Case %d:\n",++cas);
        if(q==1){
            scanf("%I64d%I64d%d%d",&x,&y,&b,&m);
            if(x>y)swap(x,y);
            printf("%I64d\n",solve1(y)-solve1(x-1));
        }
        else{
            scanf("%I64d%I64d%d%d%I64d",&x,&y,&b,&m,&k);
            if(x>y)swap(x,y);
            ll tmp=solve2();
            if(tmp!=-1)
            printf("%I64d\n",tmp);
            else
            printf("Could not find the Number!\n");
        }
    }
return 0;
}

 

HDU 3271-SNIBB(数位dp)

标签:

原文地址:http://www.cnblogs.com/zsf123/p/4680844.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!