hdu 2089 不要62 数位DP

本文介绍了一种基于数位动态规划(数位DP)的方法,用于解决特定类型的数学问题。文章详细展示了算法实现过程,包括初始化状态转移方程、处理边界条件及最终求解策略。该方法特别适用于处理数字字符串问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做法:基本数位DP了,写情况的时候小心点啊。本来想用自动机的,可是....不行啊,重叠状况难以去掉,而且下面的source简直是...

#include <iostream>
#include <cstdio>
//注意多余0的情况
const int LMT=9;
using namespace std;
int dp[LMT][10],re[LMT][10],num[LMT];
void init(void)
{
    for(int i=0;i<=9;i++)
    if(i!=4)dp[1][i]=re[1][i]=1;
    for(int i=2;i<LMT;i++)
     for(int j=0;j<=9;j++)
     if(j!=4)
     {
         for(int t=0;t<=9;t++)
         if(t!=4&&(j!=2||t!=6))
         {
             dp[i][j]+=dp[i-1][t];
             if(i==2&&t==0)
             dp[i][j]-=dp[i-1][t];
         }
     }
     for(int i=2;i<LMT;i++)
      for(int j=0;j<=9;j++)
      if(j!=4)
       for(int t=0;t<=9;t++)
       if(t!=4&&(j!=6||t!=2))
           re[i][j]+=re[i-1][t];
}
int leng(int x)
{
    int ret=0;
    do
    num[ret++]=x%10;
    while(x/=10);
    return ret;
}
int work(int x)
{
    int len=leng(x),pos=-1,res=0,end;
    for(int i=len-1;i>=0;i--)
    if(num[i]==4||(i<len-1&&num[i+1]==6&&num[i]==2))
    {
        pos=i;break;
    }
    if(pos==-1)res++;
    for(int i=len-1;i>0;i--)
     for(int j=0;j<=9;j++)
       res+=dp[i][j];
    for(int i=len-1;i>=0;i--)
    {
        if(i>=pos)
        {
            if(i==len-1&&len>1)end=1;
            else end=0;
            for(int j=num[i]-1;j>=end;j--)
            {
                res+=re[i+1][j];//要记得当前的长度啊
                if(i<len-1&&num[i+1]==6&&j==2)res-=re[i+1][j];
                //这个思考比较复杂,先写下来吧,打草稿,防止出粗,判断小于大于的时候三思啊
            }
        }
    }
    return res;
}
int main()
{
    int n,m;
    init();
    while(~scanf("%d%d",&n,&m)&&(m||n))
    printf("%d\n",work(m)-work(n-1));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值