Fork me on GitHub

数位dp(模板&&以hdu2092为例)

数位一般来说是求在一段范围内的满足某些条的数,假如说在[ri,le]的条件下满足一定条件的数的话,那么我们就可以采用差分的方法:

就是count = solve(le) - solve(ri-1);或者count = solve(le) - solve(ri) + check(ri);

 即就是满足[0,le]的数 -满足 [0,ri-1]的数;

数位dp通俗的讲就是按位上的暴力搜索然后求得的答案,我们需要从高位到低位这样搜索下去假如说我们要求满足[0,123456789]之间

某个条件的数那么我们需要先从最高位开始搜索即(1)所在的位置也就是在这个例子中的第9位在这个位置上我们可以搜索的数有(0,1)

然后我们再搜索第8位,第7位....一直到第1位,但是同时我们有不能超过所给的数字范围,所以我们在每次搜索的时候需要一个limit波尔类型

判断的数来判断他们是否达到搜索的最大值,即我们就要判断limit在上一层是否已经到达1在这层是否到达最大值的时候。其实总而言之就是dfs

对于位数上的暴力查找,然后用数组来存一下来减少一些不必要的查找。

一般来说,模板如下,这里我们以hdu2092为例

题解:我们就是从最高位开始dfs如果遇到了4就continue,如果前一位为6而遍历到这一为2时continue;最后用dp数组来存一下这时候的结果

​
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
const int INF = 0x3f3f3f3f;
int dp[11][11][2][2];
int len;
string s,t;
string s_mo;
int dfs(int cur,int x,bool limit,bool g)//cur位数  x代表前一位的数字  limit代表是否到达上界  g代表前置是否为零 
{
	if(cur==len) return 1;
	if(!limit&&dp[cur][x][limit][g]!=-1) return dp[cur][x][limit][g];
	int v = 9;
	if(limit)
	{
		v = s_mo[cur] - '0';
	}
	int ans = 0;
	for(int i=0;i<=v;i++)
	{
		if(g==1)//前导为0的情况下 
		{
			if(i==0)
			{
				ans+=dfs(cur+1,0,limit&&i==v,1);
			}
			else if(i==4){
				continue;
			}
			else{
				ans+=dfs(cur+1,i,limit&&i==v,0);
			}
		}
		else{//前导不为0的情况下 
			if((x==6&&i==2)||i==4) continue;
		    else{
			    ans+=dfs(cur+1,i,limit&&i==v,0);
		    }
		}
	}
	return dp[cur][x][limit][g] = ans;
}
int solve(string ss)
{
	mem(dp,-1);
	len = ss.size();
	s_mo = ss;
	return dfs(0,0,1,1);
	
}
bool chk(string ss)
{
	bool flag = 0;
	for(int i=0;i<ss.length();i++)
	{
		if(s[i]=='4') flag = 1;
		else if(s[i]=='6'&&s[i+1]=='2'){
			flag = 1;
		}
	}
	return 1-flag ;
}
int main()
{
    int n,m;
    while(cin>>s>>t)//输入字符串类型有利于从最高位开始遍历 
    {
    	if(s=="0"&&t=="0") break;
    	int ans = solve(t) -solve(s) + chk(s);
    	cout<<ans<<endl;
	}
    return 0;
}
 
​

  

 

posted @ 2021-01-28 16:47  lcsdsg  阅读(74)  评论(0编辑  收藏  举报
【推荐】 程序员网址大全  |  EF CodeFirst  |  百度地图.NET  |  MyNPOI  |  开源  |  我的皮肤  |  ASP.NET MVC4  |  前端提升   |  LINQ   |  WCF   |  EasyUI  |