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;
    }
    

  • 相关阅读:
    CoCreateInstace 返回未知注册类别错误
    WINCE USB驱动组入
    CreateEvent ResetEvent SetEvent
    AppWidget的范例
    ubuntu下解决无声音的方法
    计算几何与图形学有关的几种常用算法
    Android实现GPS的打开与关闭
    深入剖析Android动画(Animation) (闪烁、左右摇摆、上下晃动等效果)
    中兴手机Linux下开发的方法
    移动网络环境下ReadBuffer的使用
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10935538.html
Copyright © 2011-2022 走看看