HDU 4734 F(x)

来源:互联网 发布:我知谁掌管明天 歌词 编辑:程序博客网 时间:2024/05/16 09:27


F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... + A2 * 2 + A 1 * 1

计算 0-B 有多少数,F(i) <= F(A)。


一开始的思路,需要 开一个dp[10][1<<10] 表示当前值为F(i)的个数,那么每个案例要将F(A)求出来,然后每次dp需要初始化,这样就超时。

那么怎么让dp不用重复计算,dp[10][1<<10]表示 前i个,A的值-B当前值为j的个数,那么F[A]值作为初始值。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<stack>#include<queue>#include<deque>#include<map>#include<algorithm>using namespace std;typedef long long LL;//#pragma comment(linker, "/STACK:102400000,102400000")const double PI = acos(-1.0);const double eps = 1e-6;const int INF=0x3f3f3f3f;const int N=500010;const int mod = 1e9+7;int dp[10][9*(1<<9)];   //前i个,A的值-B前缀值为j的个数int sum;int bit[10];int dfs(int pos,int res,int limit){    //if(res < 0) return 0;    if(pos == 0)        return res >= 0;    if(!limit && dp[pos][res] != -1)            return dp[pos][res];    int up = limit?bit[pos]:9;    int ans = 0;    for(int i = 0; i <= up; i++)    {        if(res >= i*(1<<pos-1))            ans += dfs(pos-1,res-i*(1<<pos-1),limit&&i==bit[pos]);    }    if(!limit)        dp[pos][res] = ans;    return ans;}int solve(int n){    int pos = 0;    while(n)    {        bit[++pos] = n%10;        n /= 10;    }    return dfs(pos,sum,1);}int main(){    int T;    memset(dp,-1,sizeof(dp));    scanf("%d",&T);    for(int cas = 1; cas <= T; cas++)    {        int a,b;        scanf("%d%d",&a,&b);        sum = 0;        int res = 1;        while(a)        {            sum = sum+(a%10)*res;            res *= 2;            a /= 10;        }        printf("Case #%d: ",cas);        printf("%d\n",solve(b));    }    return 0;}


原创粉丝点击