• 2017广东工业大学程序设计竞赛决赛 G 等凹数字


    题意:

    Description

    定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如5432123455544334455是合法的等凹数字,543212346123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?

    Input

    第一行一个整数T,表示数据的组数。

    接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)

    Output

     输出一个整数,代表[L,R]中有多少等凹数字

    Sample Input

    2 1 100 101 200

    Sample Output

    0 1

    HINT

     小于等于2位的数字无凹峰

    思路:

    数位dp,要记录的状态为剩下的数位,等凹数的长度,前缀的最后一个数字,前缀是否上升过,前缀是否下降过,前缀是否是回文,前缀是否为0。

    在判断是否是回文的时候还要用一个数组记录前缀。

    实现:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 int num[20], buf[20], n, t;
     8 int dp[20][20][10][2][2][2];
     9 ll l, r;
    10 
    11 int dfs(int now, int len, int last, bool up, bool down, bool isP, bool lz, bool flag)
    12 {
    13     if (now == 0)
    14     {
    15         return up && down && isP;
    16     }
    17     if (!flag && dp[now][len][last][up][down][isP] != -1)
    18         return dp[now][len][last][up][down][isP];
    19     int res = 0;
    20     int u = flag ? num[now] : 9;
    21     for (int i = 0; i <= u; i++)
    22     {
    23         buf[now] = i;
    24         if (lz)
    25             res += dfs(now - 1, len - (i == 0), i, up, down, 
    26                        isP, i == 0, flag && i == u);
    27         else if (i == last)
    28         {
    29             if (isP && now <= len / 2)
    30                 res += dfs(now - 1, len, i, up, down, 
    31                            i == buf[len + 1 - now], false, flag && i == u);
    32             else
    33                 res += dfs(now - 1, len, i, up, down, 
    34                            isP, false, flag && i == u);
    35         }
    36         else if (i < last)
    37         {
    38             if (up)
    39                 continue;
    40             if (isP && now <= len / 2)
    41                 res += dfs(now - 1, len, i, false, true, 
    42                            i == buf[len + 1 - now], false, flag && i == u);
    43             else
    44                 res += dfs(now - 1, len, i, false, true, 
    45                            isP, false, flag && i == u);
    46         }
    47         else
    48         {
    49             if (!down)
    50                 continue;
    51             if (isP && now <= len / 2)
    52                 res += dfs(now - 1, len, i, true, true, 
    53                            i == buf[len + 1 - now], false, flag && i == u);
    54             else
    55                 res += dfs(now - 1, len, i, true, true, 
    56                            isP, false, flag && i == u);
    57         }
    58     }
    59     return flag ? res : dp[now][len][last][up][down][isP] = res;
    60 }
    61 
    62 int query(ll x)
    63 {
    64     memset(dp, -1, sizeof(dp));
    65     n = 0;
    66     while (x)
    67     {
    68         num[++n] = x % 10;
    69         x /= 10;
    70     }
    71     return dfs(n, n, 0, false, false, true, true, true);
    72 }
    73 
    74 int main()
    75 {
    76     cin >> t;
    77     while (t--)
    78     {
    79         scanf("%lld %lld", &l, &r);
    80         printf("%d
    ", query(r) - query(l - 1));
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    web安全之ssrf
    web安全之sql注入布尔注入
    web安全之sql注入报错型注入
    web安全之sqlload_file()和into outfile()
    浅谈 FHQ-Treap
    (菜鸟都能看懂的)网络最大流最小割,Ford-Fulkerson及Dinic详解
    浅谈最小生成树
    浅谈强连通分量(Tarjan)
    DP-DAY3游记
    关于01背包问题
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6657111.html
Copyright © 2020-2023  润新知