zoukankan      html  css  js  c++  java
  • 一本通1586:【 例 2】数字游戏

    Description

    一本通传送门

    Solution

    数位dp裸题。

    前缀和思想,(ans_{a,b}) 即为 (ans_{1,b} - ans_{1,a-1})

    讲解都在代码里。

    (dp) 过程用 (dfs) 来实现。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    int l, r;
    int num[13],dp[13][13][2];	//dp[i][j][k]:第i位,上一位是数字j,k:是否有上限(都放到状态里,懒人写法)
    
    inline int dfs(int len, int pre, int lim){		//len:当前处理到了第几位,pre:上一位是多少,lim:上一位是否取到最大值(是:这一位有上限。否:这一位可以取0~9)
    	if(!len) return 1;
    	if(dp[len][pre][lim] != -1) return dp[len][pre][lim];	//记忆化(注意判断!=-1)
    	int res = lim ? num[len] : 9;		//lim有值:上限为num[len]。没值:上限为9
    	int ans = 0;
    	for(int i = 0; i <= res; i++)
    		if(i >= pre) ans += dfs(len - 1, i, lim && (i == res));		//lim的值手玩一下就知道了(前一位和当前位都是最大值时,lim为1)
    	return dp[len][pre][lim] = ans;		//别忘了给dp赋值
    }
    
    inline int solve(int x){
    	int len = 0;
    	while(x){
    		num[++len] = x % 10;	//把x拆开,注意这里是倒着存的,所以后面从len开始dfs
    		x /= 10;
    	}
    	memset(dp, -1, sizeof(dp));
    	return dfs(len, 0, 1);
    }
    
    int main(){
    	while(scanf("%d%d", &l, &r) != EOF)
    		printf("%d
    ", solve(r) - solve(l - 1));
    	return 0;
    }
    

    End

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

  • 相关阅读:
    b站尚硅谷MySQL笔记(婷姐初级,周阳高级)
    word--公式添加编号
    excel--长数字显示问题
    R语言--蒙特卡洛计算定积分
    数学
    数学
    Computer Science
    Computer Science
    Computer Science
    元学习
  • 原文地址:https://www.cnblogs.com/xixike/p/15102378.html
Copyright © 2011-2022 走看看