数位DP 学习笔记2

小编 2026-07-07 阅读:613 评论:0
题目HDU 4734 F(x): 题目大意是给你两个数A,B,定义F(A)= 每个数位的数 * 2 ^ (位数 - 1)。求 0 - B 区间里的 F(x) <= F(A) 的数字的个数。 一个数...

题目HDU 4734 F(x):

题目大意是给你两个数A,B,定义F(A)= 每个数位的数 * 2 ^ (位数 - 1)。求 0 - B 区间里的 F(x) <= F(A) 的数字的个数。

一个数位DP的做法(TLE):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[1005], FA, poww[15], dp[15][10005];
ll dfs(ll pos, ll lim, ll hav)
{
    if(hav > FA)return 0;
    if(pos == -1)return 1;
    if(lim == 0 && dp[pos][hav] != -1)return dp[pos][hav];
    ll len = lim ? a[pos] : 9, ans = 0, i;
    for(i = 0; i <= len; i++)
    {
        if(hav + i * poww[pos] <= FA)
            ans += dfs(pos - 1, lim && (i == len), hav + i * poww[pos]);
    }
    if(lim == 0)dp[pos][hav] = ans;
    return ans;
}
ll slove(ll n, ll m)
{
    FA = 0;
    ll pos = 0, k = 1, ans;
    while(n)
    {
        FA += k * (n % 10);
        n /= 10;
        k *= 2;
    }
    while(m)
    {
        a[pos++] = m % 10;
        m /= 10;
    }
    ans = dfs(pos - 1, 1, 0);
}
int main()
{
    ll t, n, m, i, j, k = 1, ca = 1;
    for(i = 0; i <= 13; i++)poww[i] = k, k *= 2;
    scanf(\"%lld\", &t);
    while(t--)
    {
        scanf(\"%lld %lld\", &n, &m);
        memset(dp, -1, sizeof(dp));
        ll ans  = slove(n, m);
        printf(\"Case #%lld: %lld\\n\", ca++, ans);
    }
    return 0;
}

尽管加了记忆化搜索,但还是超时了,然后分析发现:

每次都要 memset(dp),用了很多时间,然后想办法优化它。

如果我们把拥有价值改变一下,变成剩余价值,即不再是它有多少,而是它还能加多少价值,这样,它的边界不再是可变的F(A),而是固定的值(0)。这样,便可以只memset(dp)一次,不需要每组都初始化了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[15];
ll dp[15][200005];
ll po[15], maxx;
ll F(ll x)
{
    ll pos = 0, ans = 0, num, pi = 1;
    while(x)
    {
        num = x % 10;
        x /= 10;
        ans += num * pi;
        pi *= 2;
    }
    return ans;
}
ll dfs(ll pos, ll sta, ll lim)
{
    if(sta < 0)return 0;
    if(pos == -1)return 1;
    if(lim == 0 && dp[pos][sta] != -1)return dp[pos][sta];
    ll len = lim ? a[pos] : 9;
    ll ans = 0;
    for(ll i = 0; i <= len; i++)
    {
        ll w = po[pos] * i;
        if(sta - w < 0)continue;
        else
        {
            ans += dfs(pos - 1, sta - w, lim && i == a[pos]);
        }
    }
    if(lim == 0)dp[pos][sta] = ans;
    return ans;
}
ll slove(ll x)
{
    ll pos = 0;
    while(x)
    {
        a[pos++] = x % 10;
        x /= 10;
    }
    ll ans = dfs(pos - 1, maxx, 1);
    return ans;
}
int main()
{
    ll t, k, i, j, m, n;
    k = 1;
    for(i = 0; i <= 15; i++)po[i] = k, k *= 2;
    scanf(\"%lld\", &t);
    for(ll q = 0; q < 15; q++)
    {
        for(ll w = 0; w < 200005; w++)dp[q][w] = -1;
    }
    for(i = 1; i <= t; i++)
    {

        scanf(\"%lld %lld\", &n, &m);
        maxx = F(n);
        //cout << maxx << endl;
        ll ans = slove(m);
        if(0 <= maxx)ans++;
        printf(\"Case #%lld: %lld\\n\",i, ans - 1);
    }
    return 0;
}

总结:遇到超时问题时可以试着转换方法,反过来考虑。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
标签列表