zoukankan      html  css  js  c++  java
  • windy数

    题目

    数位DP

    记忆化搜索来实现

    dfs设五个参数 pos,len,pre,sta,limit;

    pos为当前枚举到第几位,从高往低枚举。

    pos 为当前枚举到第几位,从高往低枚举。
    len 有没有前导零,0代表有,1代表没有
    pre 当前位的上一位
    sta 设的状态,这题有10个,为0~9分别代表当前位上是几
    limit 高位标记

    设一个 f 数组

    f[pos][pre][sta]为位数为pos,上一位为pre,当前状态为sta时的答案

    枚举每一位上的数字(0~9)

    如果有高位标记,那么最多枚举到a[pos];

    a[i]表示这个数的第i位是多少

    那么很显然当abs(pre-i)<2就得跳过这个数

    上代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int f[100][10][100],a[100];
    int dfs(int pos,int len,int sta,int pre,bool limit)
    {
    	if (pos==0) return 1;
    	if (!limit&&f[pos][sta][pre]!=-1) return f[pos][sta][pre];
    	int up=limit?a[pos]:9;//判断高位标记
    	int tmp=0;
    	for (int i=0;i<=up;i++)
    	{
    		if (pre!=-1&&abs(pre-i)<2) continue;//如果不合法就跳过
    		if (i==0&&len==0) tmp+=dfs(pos-1,0,0,-1,limit&&i==a[pos]);
    		else
    		{
    			tmp+=dfs(pos-1,1,i,i,limit&&i==a[pos]);
    		}
    	}
    	if(!limit) f[pos][sta][pre]=tmp;
    	return tmp;
    }
    int solve(int x)
    {
    	int cnt=0;
    	while (x!=0)
    	{
    		a[++cnt]=x%10;
    		x=x/10;
    	}
    	dfs(cnt,0,0,-1,true);
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m); 
    	memset(f,-1,sizeof(f));
    	printf("%d
    ",solve(m)-solve(n-1));
    }
    

      

  • 相关阅读:
    css3简易实现图标动画由小到大逐个显现
    下拉图标呼吸效果制作
    设置图片从页面四周渐入效果的锚点方法
    关于导航宽度高度自适应的小栗子
    Odd-e CSD Course Day 5
    Odd-e CSD Course Day 2
    Odd-e CSD Course Day 3
    Odd-e CSD Course Day 1
    Odd-e CSD Course Day 4
    [心得] SQL Server Partition(表分區) 資料分佈探討
  • 原文地址:https://www.cnblogs.com/nibabadeboke/p/11328096.html
Copyright © 2011-2022 走看看