现在的位置: 首页 > 综合 > 正文

HDU 4734 F(x)

2013年02月13日 ⁄ 综合 ⁄ 共 2770字 ⁄ 字号 评论关闭

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734

题意:对于一个n位的十进制数字x=(AnAn-1An-2 ... A2A1),定义 F(x)=An*2n-1+An-1*2n-2+ ...+A2*2+A1*1。给出A、B,求在[0,B]之间有多少数字满足F(x)<=F(A)?


思路:数位DP。f[dep][x]表示到达dep剩余为x的方案数。


#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>
#include <ctype.h>
#include <time.h>
        
        
#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define MP(x,y) make_pair(x,y)
#define EPS 1e-6
        
        
#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define FORL0(i,a) for(i=a;i>=0;i--)
#define FORL1(i,a) for(i=a;i>=1;i--)
#define FORL(i,a,b)for(i=a;i>=b;i--)
        
        
#define rush() int CC;for(scanf("%d",&CC);CC--;)
#define Rush(n)  while(scanf("%d",&n)!=-1)
using namespace std;
        
        
void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%lld",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%lld%lld",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%lld%lld%lld",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
        
        
void PR(int x) {printf("%d\n",x);}
void PR(int x,int y) {printf("%d %d\n",x,y);}
void PR(int x,int y,int z) {printf("%d %d %d\n",x,y,z);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(i64 x,i64 y) {printf("%lld %lld\n",x,y);}
void PR(double x) {printf("%.2lf\n",x);}
void PR(double x,double y) {printf("%.5lf %.5lf\n",x,y);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
   
   
void upMin(int &x,int y) {if(x>y) x=y;}
void upMin(i64 &x,i64 y) {if(x>y) x=y;}
void upMin(double &x,double y) {if(x>y) x=y;}
void upMax(int &x,int y) {if(x<y) x=y;}
void upMax(i64 &x,i64 y) {if(x<y) x=y;}
void upMax(double &x,double y) {if(x<y) x=y;}
        
const int mod=30031;
const i64 inf=((i64)1)<<60;
const double dinf=1000000000000000000.0;
const int INF=1000000000;
const int N=100005;

i64 n,m;
i64 f[25][N];
int a[25],num;

i64 Sum;

i64 DFS(int dep,int flag,int cur)
{
    if(cur<0) return 0;
    if(dep==-1) return 1;
    if(!flag&&f[dep][cur]!=-1) return f[dep][cur];
    int M=flag?a[dep]:9;
    i64 ans=0,i;
    for(i=0;i<=M;i++)
    {
        ans+=DFS(dep-1,flag&&i==M,cur-i*(1<<dep));
    }
    if(!flag) f[dep][cur]=ans;
    return ans;
}

i64 cal()
{
    num=0;
    while(n) a[num++]=n%10,n/=10;
    Sum=0;
    int i,j;
    FOR0(i,num) Sum+=a[i]*(1<<i);
    num=0;
    while(m) a[num++]=m%10,m/=10;
    return DFS(num-1,1,Sum);
}

int main()
{
    clr(f,-1);
    int num=0;
    rush()
    {
        scanf("%I64d%I64d",&n,&m);
        printf("Case #%d: %I64d\n",++num,cal());
    }
}

抱歉!评论已关闭.