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

HDU3734 F(x)

时间:2019-07-18 13:30:13      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:cli   open   nbsp   需要   case   sub   tom   for   ane   

题目描述

For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).

 Input

The first line has a number T (T <= 10000) , indicating the number of test cases.
For each test case, there are two numbers A and B (0 <= A,B < 109)

Output

For every case,you should output "Case #t: " at first, without quotes. The t is the case number starting from 1. Then output the answer.

题解

可以观察到位数只有9位,F(x)的值不会超过4599,那么很容易可以得到状态f[pos][sum]

技术图片
#include<bits/stdc++.h>
using namespace std;

int t,pow2[15];
int a,b;
int len,num[10];
int f[10][10000][2];

void get_fa(int &a){
    int x=0,cnt=0;;
    while(a){
        x+=pow2[cnt++]*(a%10);
        a/=10;
    }
    a=x;
}

int dfs(int s,int sum,bool lim){
    if(sum>a) return 0;
    if(!s) return 1;
    if(f[s][sum][lim]!=-1) return f[s][sum][lim];
    int mx= lim ? num[s] : 9 ;
    int ret=0;
    for(int i=0;i<=mx;i++)
     ret+=dfs(s-1,sum+i*pow2[s-1],lim&&i==mx);
    return f[s][sum][lim]=ret;
}

int cx(int x){
    len=0;
    while(x){
        num[++len]=x%10;
        x/=10;
    }
    memset(f,-1,sizeof(f));
    return dfs(len,0,true);
}

void nice(int i){
    scanf("%d%d",&a,&b);
    get_fa(a);
    //printf("%d\n",a);
    printf("Case #%d: %d\n",i,cx(b));
}

int main(){
    pow2[0]=1;
    for(int i=1;i<=10;i++) pow2[i]=pow2[i-1]*2;
    scanf("%d",&t);
    for(int i=1;i<=t;i++) nice(i);
}
View Code

然后疯狂TTTTTTT掉

因为对于每组数据都要将f初始化,然后不要脸的去看了博客

发现可以改变数组状态,第二位定义为与f(x)的差,就只需要在最初初始化,不过不能开lim这一维

简直妙啊

技术图片
#include<bits/stdc++.h>
using namespace std;

int t,pow2[15];
int a,b;
int len,num[10];
int f[10][4600];

void get_fa(int &a){
    int x=0,cnt=0;;
    while(a){
        x+=pow2[cnt++]*(a%10);
        a/=10;
    }
    a=x;
}

int dfs(int s,int sum,bool lim){
    if(sum<0) return 0;
    if(!s) return 1;
    if(!lim&&f[s][sum]!=-1) return f[s][sum];
    int mx= lim ? num[s] : 9 ;
    int ret=0;
    for(int i=0;i<=mx;i++)
     ret+=dfs(s-1,sum-i*pow2[s-1],lim&&i==mx);
    if(!lim) f[s][sum]=ret;
    return ret;
}

int cx(int x){
    len=0;
    while(x){
        num[++len]=x%10;
        x/=10;
    }
    return dfs(len,a,true);
}

void nice(int i){
    scanf("%d%d",&a,&b);
    get_fa(a);
    //printf("%d\n",a);
    printf("Case #%d: %d\n",i,cx(b));
}

int main(){
    pow2[0]=1;
    for(int i=1;i<=10;i++) pow2[i]=pow2[i-1]*2;
    memset(f,-1,sizeof(f));
    scanf("%d",&t);
    for(int i=1;i<=t;i++) nice(i);
}
View Code

 

HDU3734 F(x)

标签:cli   open   nbsp   需要   case   sub   tom   for   ane   

原文地址:https://www.cnblogs.com/sto324/p/11206620.html

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