zoukankan      html  css  js  c++  java
  • hdu5179 beautiful number

    因为递推版本的数位dp容易错 (主要还是我不会写),所以选择了记忆化搜索的方式。

    详见代码。

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int digit[100];/*digit[]:存储每个数字*/
    int dp[20][20];/*记忆化数组*/
    int dfs(int step/*当前的数位编号*/,int pre/*上一个数字*/,bool zero/*是否有前导零*/,bool lmt/*是否有数字的上限*/) 
    {
    	if(!step) return 1;/*找到一个可行解*/
    	if(dp[step][pre] && !zero && !lmt) return dp[step][pre];/*已经搜过,无需再次搜索(记忆化)*/
    	int high=(lmt ? digit[step] :9)/*可以循环到的最高位*/,ans=0;
    	for(int i=0;i<=high;i++)
    		if(zero || (i && pre%i==0 && pre>=i))/*当前这个数字可以*/
    			ans+=dfs(step-1,i,zero && i==0,lmt && i==digit[step]);
    	if(!lmt && !zero) dp[step][pre]=ans;/*记忆化*/
    	return ans;
    }
    int solve(int n)/*回答每个询问*/
    {
    	int len=0;
    	while(n)
    	{
    		digit[++len]=n%10;
    		n/=10;
    	}/*存储每一位(倒序)*/
    	return dfs(len,-1,true,true);/*由于倒序存储(见上面的循环),需要从len枚举到1*/
    }
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    	    memset(dp,0,sizeof(dp));
    		int l,r;
    		scanf("%d %d",&l,&r);
    		printf("%d
    ",solve(r)-solve(l-1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    递归和回溯_leetcode-floodfill
    递归和回溯_leetcode131
    递归和回溯_leetcode130
    递归和回溯_leetcode93-经典的回溯题
    递归和回溯_leetcode90
    递归和回溯_leetcode79
    递归和回溯_leetcode78-经典的子集
    知识树杂谈(1)
    Android 设备兼容性(1)
    微信小程序- 生成二维码
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/12284173.html
Copyright © 2011-2022 走看看