• hdu 2089(数位dp)


    这道题应该是最简单的数位dp了,看了09年的刘聪的国家集训队论文,入门了一下数位dp。解决这道题还是花了我好长的一段时间。

    这里就先讲一下我是如何用数位dp解这道题的,感觉后面还是要写一篇数位dp的总结。首先是状态的确定,数位dp的基本状态往往是dp[i, ...]i表示枚举到的位数,后面是需要的状态。对于这道题,我列举了一个状态就是dp[i][j]表示枚举到第i位第一个数字是j所包含的合法数字数。

    程序结构:

    初始化的时候把dp数组先预处理出来,后面写个solve(x)表示当前数前面的合法数个数。那ans = solve(b+1)-solve(a)。

    关键在于处理solve(x)的计算。首先是枚举每一位,然后是枚举每一位可能出现的值,注意在枚举值得时候一旦前面已经枚举的数中已经出现4或者是62直接break。

    若是前一位确定为6这一位枚举到2 或者 这一位为4 continue,这应该都比较好理解。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #define LEN 30
     8 using namespace std;
     9 
    10 int a, b, dp[LEN][LEN];
    11 
    12 void init()
    13 {
    14     memset(dp, 0, sizeof dp);
    15     for(int i=0; i<LEN; i++){
    16         if(i!=4) dp[1][i] = 1;
    17     }
    18     for(int i=2; i<LEN; i++){
    19         for(int j=0; j<10; j++){
    20             if(j==4) continue;
    21             for(int k=0; k<10; k++){
    22                 if((j==6 && k==2) || k==4)continue;
    23                 dp[i][j] += dp[i-1][k];
    24             }
    25         }
    26     }
    27 }
    28 
    29 
    30 int solve(int x)
    31 {
    32     char str[100] = {0};
    33     sprintf(str+1, "%d", x);
    34     int len = strlen(str+1), ret = 0;
    35     for(int i=len; i>=1; i--){
    36         int pos = len-i+1, num = str[pos]-'0';
    37         for(int j=0; j<num; j++){
    38             if(j==4 || (j==2 && str[pos-1]=='6'))continue;
    39             ret += dp[i][j];
    40         }
    41         if(num==4 || (num==2 && str[pos-1]=='6')) break;
    42     }
    43     return ret;
    44 }
    45 
    46 int main()
    47 {
    48 //    freopen("in.txt", "r", stdin);
    49 
    50     while(scanf("%d%d", &a, &b)!=EOF)
    51     {
    52         if(a==0 && b==0)break;
    53         init();
    54         int ans = solve(b+1) - solve(a);
    55         printf("%d
    ", ans);
    56     }
    57     return 0;
    58 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    oracle expdp和impdp常用命令选项
    oracle expdp导出远程数据到本地
    oracle目录操作
    反射
    设置查询对话框的F7
    Uncaught TypeError: timeout.close is not a function. when try to use clearInterval
    timestamp to time 时间戳转日期
    react+antd 选项卡切换
    react antd Warning: must set key for <rc-animate> children
    微信企业号报Error: echostr校验失败,请您检查是否正确解密并输出明文
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3438470.html
Copyright © 2020-2023  润新知