zoukankan      html  css  js  c++  java
  • hdu3652(数位dp)

    题意:求1-n(n<=1000000000)的数中,技能被13整除。又包括13子串的数的个数;


    解法:数位dp。LL dp[pre][now][have][iflow][rem]记录着第pre位为now,have表示前边是否出现过13,iflow表示dp过程否有减少,rem表示兴许须要的余数是多少。


    代码:

    /******************************************************
    * author:xiefubao
    *******************************************************/
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <string.h>
    //freopen ("in.txt" , "r" , stdin);
    using namespace std;
    
    #define eps 1e-8
    const double pi=acos(-1.0);
    typedef long long LL;
    const int Max=10100;
    const int INF=1000000007;
    LL dp[20][20][2][2][15];
    int reminder[20];
    int num[30];
    LL dfs(int pre,int now,bool have,bool iflow,int rem)
    {
        if(pre==0)
            return have&&rem==0;
        if(dp[pre][now][have][iflow][rem]!=-1)
            return dp[pre][now][have][iflow][rem];
        int en=iflow? 9 : num[pre-1];
        LL ans=0;
        for(int i=0;i<=en;i++)
        {
            int tool=((rem-(i*reminder[pre-1])%13)+13)%13;
            if(now==1&&i==3)
            ans+=dfs(pre-1,i,1,iflow||i!=en,tool);
            else
            ans+=dfs(pre-1,i,have,iflow||i!=en,tool);
        }
        return dp[pre][now][have][iflow][rem]=ans;
    }
    void init()
    {
        reminder[0]=1;
        for(int i=1;i<=10;i++)
            reminder[i]=(reminder[i-1]*10)%13;
    }
    LL solve(LL n)
    {
        int p=0;
        memset(dp,-1,sizeof dp);
        while(n)
        {
            num[p++]=n%10;
            n/=10;
        }
        LL ans=0;
        for(int i=0;i<=num[p-1];i++)
        {
            int tool=(i*reminder[p-1])%13;
            ans+=dfs(p-1,i,0,i!=num[p-1],(13-tool)%13);
        }
        return ans;
    }
    int main()
    {
      int n;
      init();
      while(cin>>n)
      {
          cout<<solve(n)<<'
    ';
      }
       return 0;
    }
    

  • 相关阅读:
    Java开发常用Util工具类
    冒泡排序
    EMQ 消息服务器
    将jar文件包打成exe文件
    mina框架搭建tcp服务器:编写自定义协议及编解码器
    SpringBoot中定时任务的设置
    SpringBoot项目+Shiro(权限框架)+Redis(缓存)集成
    计算两个时间之间的天数
    关于extern的使用
    ADC采样间隔问题+TRGO作为ADC的触发源头
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10935538.html
Copyright © 2011-2022 走看看