• 数位DP


      萌新第一题:HDU2089 不要62 

     1 #include <iostream>
     2 #include <string.h>
     3 #include <cstdio>
     4 #include <queue>
     5 #include <math.h>
     6 #include <string>
     7 #include <map>
     8 #include <algorithm>
     9 
    10 #define SIGMA_SIZE 26
    11 #pragma warning ( disable : 4996 )
    12 
    13 using namespace std;
    14 typedef long long LL;
    15 
    16 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
    17 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
    18 inline int Max(int a,int b) { return a>b?a:b; }
    19 inline int Min(int a,int b) { return a>b?b:a; }
    20 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
    21 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
    22 const int inf  = 0x3f3f3f3f;
    23 const int mod  = 100000000;
    24 const int maxn = 1e6+5;
    25 const int maxk = 200;
    26 
    27 int dp[20][2];
    28 int num[20];
    29 
    30 int find( int pos, int pre, int sta, bool limit )
    31 {
    32     if ( pos == -1 ) return 1;
    33     if ( !limit && dp[pos][sta] != -1 ) return dp[pos][sta];
    34     int up = limit?num[pos]:9;
    35     int tmp = 0; 
    36     for ( int i = 0; i <= up; i++ )
    37     {
    38         if ( pre == 6 && i == 2 ) continue;
    39         if ( i == 4 ) continue;
    40         tmp += find(pos-1, i, i==6, limit&&i==num[pos]);
    41     }
    42 
    43     if (!limit) dp[pos][sta] = tmp;
    44     return tmp;
    45 }
    46 
    47 int solve( int x )
    48 {
    49     int pos = 0;
    50     while(x)
    51         { num[pos++] = x % 10; x /= 10; }
    52 
    53     return find( pos-1, -1, 0, true );
    54 }
    55 
    56 int main()
    57 {
    58     int lhs, rhs;
    59     while ( ~scanf("%d %d", &lhs, &rhs) && lhs && rhs )
    60     {
    61         memset( dp, -1, sizeof(dp) );
    62         printf( "%d
    ", solve(rhs)-solve(lhs-1) );
    63     }
    64     return 0;
    65 }
    View Code

      萌新第二题:HDU3652 B数...

     有点巧妙啊,第一题只是相当于把题解抄下来了,再做这道题稍微有点感觉了,详细见注释 

     1 #include <iostream>
     2 #include <string.h>
     3 #include <cstdio>
     4 #include <queue>
     5 #include <math.h>
     6 #include <string>
     7 #include <map>
     8 #include <algorithm>
     9 
    10 #define SIGMA_SIZE 26
    11 #pragma warning ( disable : 4996 )
    12 
    13 using namespace std;
    14 typedef long long LL;
    15 
    16 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
    17 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
    18 inline int Max(int a,int b) { return a>b?a:b; }
    19 inline int Min(int a,int b) { return a>b?b:a; }
    20 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
    21 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
    22 const int inf  = 0x3f3f3f3f;
    23 const int mod  = 100000000;
    24 const int maxn = 1e6+5;
    25 const int maxk = 200;
    26 
    27 //dp[i][j][k] i:位数 j:余数 k:0表示前面不是1,1表示前面是1,2表示前面已经有13了
    28 int dp[15][15][3];
    29 int bit[15];
    30 
    31 int find(int pos, int mod, int pre, bool lim )
    32 {
    33     if ( pos == -1 ) return ( mod == 0 && pre == 2 );
    34 
    35     // 务必理解什么是记忆化
    36     if ( !lim && dp[pos][mod][pre] != -1 ) return dp[pos][mod][pre];
    37     
    38     int num = lim?bit[pos]:9;
    39 
    40     int tmp = 0;
    41     for ( int i = 0; i <= num; i++ )
    42     {
    43         int mmod = (mod*10 + i) % 13;    //其实就是做了一个除法,拿笔做演算下,比如计算2333除以13,
    44                                         //就知道这一步是什么意思了
    45         
    46         int ppre = 0;                //初始设为0
    47         if ( pre == 0 && i == 1 )    //如果前面不是1,现在是1
    48             ppre = 1;
    49         if ( pre == 1 && i == 1 )    //如果前面是1,现在还是1
    50             ppre = 1;
    51         if ( pre == 1 && i == 3 )    //如果前面是1, 现在是3
    52             ppre = 2;
    53         if ( pre == 2 ) ppre = 2;
    54 
    55         tmp += find( pos-1, mmod, ppre, lim&&i==bit[pos] );
    56     }
    57 
    58     //注意对有lim的处理(实际上有lim的计算很少)
    59     //仔细想想,当lim为true的时候,那么上面的for循环就不完整,也就是num可能不为9
    60     //既然该状态不完整,所以不能记忆保存下来啦!
    61     if (!lim) dp[pos][mod][pre] = tmp;
    62     return tmp;
    63 }
    64 
    65 int solve( int x )
    66 {
    67     int pos = 0;
    68     while(x)
    69         { bit[pos++] = x%10; x/=10; }
    70 
    71     return find(pos-1, 0, 0, true);
    72 }
    73 
    74 int main()
    75 {
    76     int rhs; 
    77     
    78     while ( ~scanf("%d", &rhs) )
    79     {
    80         memset( dp, -1, sizeof(dp) );
    81         memset( bit, 0, sizeof(bit) );
    82         printf( "%d
    ", solve(rhs) ); 
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    python多版本切换
    python之禅
    Python int与string之间的转化
    pycharm工具使用
    python学习路线图
    traceback.print_exc()的用法
    他人学习Python感悟
    【西北师大-19软工】第十三、十四次作业汇总暨期末总结
    【西北师大-19软工】第十二次作业成绩汇总
    第十七周助教工作总结——NWNU李泓毅
  • 原文地址:https://www.cnblogs.com/chaoswr/p/8799158.html
Copyright © 2020-2023  润新知