• 洛谷 P6218 [USACO06NOV] Round Numbers S


    原题链接

    数位dp

    一道小清新数位dp题。

    乍一看,诶,这不就是个板子嘛。

    但是写着写着就发现还是有蛮多细节的,下面我们来分析一下:

    直接来看核心代码(即 (dfs) 部分)

    ll dfs(ll len, ll cha, ll flag, ll lim){
    	if(!len) return cha >= 30;
    	if(dp[len][cha][flag][lim] != -1) return dp[len][cha][flag][lim];
    	ll res = lim ? num[len] : 1;
    	ll ans = 0;
    	for(ll i = 0; i <= res; i++)
    		ans += dfs(len - 1, cha + (!i ? (flag ? 0 : 1) : -1), flag && (!i), lim && (i == res));
    	return dp[len][cha][flag][lim] = ans;
    }
    

    变量解释:

    (len:) 倒着查找到了第几位

    (cha:) 0 比 1 多几个,注意可能 1 比 0 多,即 (cha < 0),作为数组下标的话会 (RE),(酱紫一点都不好哇QWQ),所以我们深搜时,令 (cha) 初值为 30,就解决问题了

    (flag:) 当前位是否为前导 0 (1:是 $ $ 0:否)

    (lim:) 当前位是否有上界限制(1:有 $ $ 0:无)

    再来看

    cha + (!i ? (flag ? 0 : 1) : -1)
    

    如果当前位是 0,但是是前导 0,那么 (cha) 不变,如果不是是前导0,那么 (cha++)

    如果当前位是 1,那么 (cha--)

    其余的就没什么难点啦,不要忘记开 (long long)

    上完整代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    #define ll long long
    
    using namespace std;
    
    ll l, r, len;
    ll num[100];
    ll dp[100][100][2][2];
    
    ll dfs(ll len, ll cha, ll flag, ll lim){
    	if(!len) return cha >= 30;
    	if(dp[len][cha][flag][lim] != -1) return dp[len][cha][flag][lim];
    	ll res = lim ? num[len] : 1;
    	ll ans = 0;
    	for(ll i = 0; i <= res; i++)
    		ans += dfs(len - 1, cha + (!i ? (flag ? 0 : 1) : -1), flag && (!i), lim && (i == res));
    	return dp[len][cha][flag][lim] = ans;
    }
    
    ll solve(ll x){
    	len = 0;
    	while(x){
    		num[++len] = x % 2;
    		x /= 2;
    	}
    	memset(dp, -1, sizeof(dp));
    	return dfs(len, 30, 1, 1);
    }
    
    signed main(){
    	scanf("%lld%lld", &l, &r);
    	printf("%lld
    ", solve(r) - solve(l - 1));
    	return 0;
    }
    

    完结撒花~

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15105436.html

  • 相关阅读:
    ASP.NET Core MVC Razor小记
    ASP.NET Core引入第三方日志框架及简单实现日志策略配置
    test
    记录一个Windows explorer进程卡死的处理,有关于“MicrosoftWindows.Client.CBS_cw5n1h2txyewy”的,已解决!
    Windows版本sed工具
    相同xml批量创建替换脚本.sh
    springboot1.x apollo 更改属性值不起作用。 ConfigurationProperties
    jmeter固定定时器
    jmeter函数助手参数化
    jmeter循环控制器
  • 原文地址:https://www.cnblogs.com/xixike/p/15105436.html
Copyright © 2020-2023  润新知