HDU---4734: F(x) 【数位dp】

本文探讨了如何优化动态规划算法,以解决特定计数问题中的Time Limit Exceeded (TLE)错误。通过实例分析,文章展示了如何通过记忆化搜索和状态转移,有效减少重复计算,提高算法效率。

题意:

给定F(x)的计算公式,求【0,b】范围内F(x) < F(a)的x的个数

分析:

笔者看完此题不假思索就开始写了,交上去就TLE,原因在于组数t很大,而dp数组记忆的是等于F(a)的个数,每次都要初始化dp数组,考虑记忆F(a)与F(x)的差,这个状态与a是没有关系的,好比F(x)==2,F(a)==5 与 F(x)==4,F(a)==7的个数是一样的

代码:

#include <bits/stdc++.h>
using namespace std;
int a,b,t,dp[12][5100],dit[12],sum;
int dfs(int pos,int val,int limit)
{
  if(pos < 0) return val >= 0;
  if(val < 0) return 0;
  if(!limit && dp[pos][val]) return dp[pos][val];
  int up = limit ? dit[pos] : 9;
  int res = 0;
  for(int i = 0;i <= up; ++i)
  {
    res += dfs(pos-1,val - (int)pow(2,pos)*i,limit && dit[pos] == i);
  }
  if(!limit) dp[pos][val] = res;
  return res;
}
void cal()
{
  sum = 0;
  int x = 0;
  while(a)
  {
    sum += a % 10 * pow(2,x);
    x++;
    a /= 10;
  }
}
int solve(int x)
{
  cal();
  int len = 0;
  while(x)
  {
    dit[len++] = x % 10;
    x /= 10;
  }
  return dfs(len-1,sum,1);
}
int main()
{
  scanf("%d",&t);
  for(int tt = 1;tt <= t; ++tt)
  {
    scanf("%d %d",&a,&b);
    printf("Case #%d: %d\n", tt,solve(b));
  }
  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值