zoukankan      html  css  js  c++  java
  • hdu 2089 不要62 hdu 3555 Bomb (数位DP)

    hdu 2089 不要62

    题意:给出两个数,求区间内不带4和62的数的个数。(PS:62是连续的两位)

    思路:

    dp[i][0]表示前i位不含不吉利数的个数(如i=4,则范围为0~9999,下同)

    dp[i][1]表示前i位不含不吉利数且首位是2的数的个数

    dp[i][2]表示前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][0] + dp[i-1][1] 

    预处理得到dp数组

    然后从高往低逐位求答案。

    例子,如数5678

    0~4999

    5000~5599

    5600~5669

    5670~5678

    的顺序求解。 

    最低位处处理要特别留意。

    参考:http://blog.csdn.net/acm_cxlove/article/details/7819907 

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 int dp[10][3], bit[10];
     5 
     6 void init()
     7 {
     8 
     9     dp[1][0] = 9; dp[1][1] = 1; dp[1][2] = 1;
    10     for(int i=2; i<=6; i++)
    11     {
    12         dp[i][0] = dp[i-1][0] * 9 - dp[i-1][1];
    13         dp[i][1] = dp[i-1][0];
    14         dp[i][2] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2] * 10;
    15     }
    16 }
    17 
    18 int solve(int n)
    19 {
    20     memset(bit, 0sizeof(bit));
    21     int len = 0;
    22     while(n>0)
    23     {
    24         bit[++len] = n%10;
    25         n /= 10;
    26     }
    27     bit[len+1] = 0;
    28     int ret = 0, flag = 0;
    29     for(int i=len; i>=2; i--)
    30     {
    31         ret += dp[i-1][2] * bit[i];
    32         if(flag==1)
    33             ret += dp[i-1][0] * bit[i];
    34         if(flag==0 && bit[i]>4)
    35             ret += dp[i-1][0];
    36         if(flag==0 && bit[i+1]==6 && bit[i]>2)
    37             ret += dp[i][1];
    38         if(flag==0 && bit[i]>6)
    39             ret += dp[i-1][1];
    40         if(bit[i]==4 || bit[i]==2 && bit[i+1]==6)
    41             flag = 1;
    42     }
    43     if(flag==1) ret += bit[1] + 1;
    44     if(flag==0 && bit[1]>=4) ret++;
    45     if(flag==0 && bit[1]>=2 && bit[2]==6) ret++;
    46     return ret;
    47 }
    48 
    49 int main()
    50 {
    51     int l, r;
    52     init();
    53 /*
    54     for(int i=1; i<=6; i++)
    55     {
    56         for(int j=0; j<=2; j++)
    57             printf("%d ",dp[i][j]);
    58         printf(" ");
    59     }
    60 */
    61     while(scanf("%d%d",&l,&r)!=EOF)
    62     {
    63         if(l==0 && r==0break;
    64 
    65         if(l>r)
    66         {
    67             int temp;
    68             temp = l; l = r; r = temp;
    69         }
    70         int ans = solve(r) - solve(l-1);
    71         //printf("%d %d %d ",solve(l),solve(r),ans);
    72         printf("%d ",r-l+1-ans);
    73     }
    74     return 0;
    75 }
    View Code

    hdu3555

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 __int64 dp[25][3];
     5 int bit[25];
     6 
     7 void init()
     8 {
     9     dp[1][0] = 10; dp[1][1] = 1; dp[1][2] = 0;
    10     for(int i=2; i<=19; i++)
    11     {
    12         dp[i][0] = dp[i-1][0] * 10 - dp[i-1][1]; //不含49数
    13         dp[i][1] = dp[i-1][0]; //不含49首位为9的数
    14         dp[i][2] = dp[i-1][1] + dp[i-1][2]*10//含49数
    15     }
    16 }
    17 
    18 __int64 solve(__int64 n)
    19 {
    20     int len = 0;
    21     while(n>0)
    22     {
    23         bit[++len] = n%10;
    24         n /= 10;
    25     }
    26     bit[len+1] = 0;
    27 
    28     __int64 ret = 0;
    29     int flag = 0;
    30     for(int i=len; i>=2; i--)
    31     {
    32         ret += dp[i-1][2] * bit[i];
    33         if(flag==1)
    34             ret += dp[i-1][0] * bit[i];
    35         if(flag==0 && bit[i]>4)
    36             ret += dp[i-1][1];
    37         if(bit[i+1]==4 && bit[i]==9)
    38             flag = 1;
    39     }
    40     if(flag==1) ret += bit[1] + 1;                 //这两行调很久
    41     if(flag==0 && bit[2]==4 && bit[1]==9) ret++;
    42     return ret;
    43 }
    44 
    45 int main()
    46 {
    47     int t;
    48     __int64 n;
    49     init();
    50     scanf("%d",&t);
    51     while(t--)
    52     {
    53         scanf("%I64d",&n);
    54         printf("%I64d ",solve(n));
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    OSPF Configuration Examples
    enabling ip forwarding
    LeetCode 153. Find Minimum in Rotated Sorted Array
    洛谷 P1059 明明的随机数
    LeetCode 120. Triangle
    洛谷 P1047 校门外的树(待完善)
    C++万能头文件<bits/stdc++.h>的内容与优缺点
    LeetCode 217. Contains Duplicate
    LeetCode 414. Third Maximum Number
    洛谷 P1540 机器翻译
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3562065.html
Copyright © 2011-2022 走看看