现在的位置: 首页 > 综合 > 正文

HDU 2089【数位DP】

2017年11月21日 ⁄ 综合 ⁄ 共 1585字 ⁄ 字号 评论关闭

和49那题是一样的,就是判断的时候会多一两个判断,然后就是要注意每次算出来的结果都是在小于n的情况下成立的。

#include <stdio.h>
#include <string.h>
#define ll __int64
ll dp[25][3];
ll solve(ll n)
{
    ll i,j,k;
    j=n;
    int top=0;
    ll que[25];
    memset(que,0,sizeof(que));
    while(j)
    {
        que[++top]=j%10;
        j/=10;
    }
    k=0;
    int flag=0;
  //  for(i=1;i<=top;i++) printf("**%d",que[i]);printf("\n");
    //int que[25];
  //  memset(que,0,sizeof(que));
    for(i=top;i>=1;i--)
    {
        k+=dp[i-1][2]*que[i];
        if(flag) k+=dp[i-1][0]*que[i];
        else
        {
            if(que[i]>6) k+=dp[i-1][1];
            if(que[i]>4) k+=dp[i-1][0];
            if(que[i+1]==6&&que[i]>2) k+=dp[i][1];
        }
        if(que[i+1]==6&&que[i]==2||que[i]==4) flag=1;
    }
    return k;
}
int main()
{
    ll n,m;
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;          //这里注意初始化
    for(int i=1;i<=20;i++)
    {
        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0];
    }
    while(scanf("%I64d%I64d",&n,&m)!=EOF&&n+m)
    {
        ll ans,tmp;
        ans=solve(n);
        tmp=solve(m+1);    //注意这里放的是m
      //  printf("**%I64d  %I64d\n",ans,tmp);
        printf("%I64d\n",m-n+1-tmp+ans);
    }
    return 0;
}

**********************************************

用DFS写的,,,其实看过很多dfs的DP,然后平生最恨这样写!!。。。。。但是自己写了之后其实感觉还不错。。。。。

state表示之前是否有6,fp大概表示是否达到了原值的那个数字。

#include <stdio.h>
#include <string.h>
#define ll __int64
ll que[30];
ll dp[30][2];
ll dfs(int len,int state,int fp)
{
    if(!len) return 1;
    if(dp[len][state]!=-1&&!fp) return dp[len][state];
    int i,j,k;
    ll ret=0;
    int fmax=fp?que[len]:9;
    for(i=0;i<=fmax;i++)
    {
        if(i==4||i==2&&state) continue;
        ret+=dfs(len-1,i==6,fp&&i==fmax);
    }
    if(!fp) dp[len][state]=ret;
    return ret;
}
ll solve(ll n)
{
    ll i,j,k;
    j=n;
    k=0;
    while(j)
    {
        que[++k]=j%10;
        j/=10;
    }
    return dfs(k,0,1);
}
int main()
{
    ll n,m;
    memset(dp,-1,sizeof(dp));
    while(scanf("%I64d%I64d",&n,&m)!=EOF&&n+m)
    {
        ll a,b;
        a=solve(n-1);
        b=solve(m);
        printf("%I64d\n",b-a);
    }
    return 0;
}

抱歉!评论已关闭.