HDU

题意:找0到B中权值小于等于A权值的数目(权值按每个位数上的二进制计算)

dp[i][j]  i-长度为i,j-权值,dp[i][j代表长度为i,小于j的个数

刚开始把j代表f(x),但是当a,不同时,dp结果不同这样会超时

#include<bits/stdc++.h>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-7;
const int N=10+10,maxn=20000+10,inf=0x3f3f3f;

int digit[N],dp[N][maxn];
int dfs(int len,int sum,bool fp)
{
    if(!len)return sum>=0;
    if(sum<0)return 0;
    if(!fp&&dp[len][sum]!=-1)return dp[len][sum];
    int ans=0,fpmax=fp ? digit[len] : 9;
    for(int i=0;i<=fpmax;i++)
    {
        ans+=dfs(len-1,sum-i*(1<<(len-1)),fp&&i==fpmax);
    }
    if(!fp)dp[len][sum]=ans;
    return ans;
}
int f(int a)
{
    int ans=0,len=0;
    while(a)
    {
        ans+=(1<<len)*(a%10);
        len++;
        a/=10;
    }
    return ans;
}
int solve(int a,int b)
{
    int len=0;
    while(b)
    {
        digit[++len]=b%10;
        b/=10;
    }
    return dfs(len,f(a),1);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t,a,b,cnt=0;
    cin>>t;
    memset(dp,-1,sizeof dp);
    while(t--){
        cin>>a>>b;
        cout<<"Case #"<<++cnt<<": "<<solve(a,b)<<endl;
    }
    return 0;
}
/********************
dp[i][j]  i-长度为i,j-权值,dp[i][j代表长度为i,小于j的个数
********************/
View Code
原文地址:https://www.cnblogs.com/acjiumeng/p/7435167.html