codeforces Hill Number 数位dp

Posted sweatOtt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces Hill Number 数位dp相关的知识,希望对你有一定的参考价值。

http://www.codeforces.com/gym/100827/attachments

 

 Hill Number


Time Limits:  5000 MS   Memory Limits:  200000 KB

64-bit interger IO format:  %lld   Java class name:  Main



Description

A Hill Number is a number whose digits possibly rise and then possibly fall, but never fall and then rise.

• 12321 is a hill number.
• 101 is not a hill number.
• 1111000001111 is not a hill number.

Given an integer n, if it is a hill number, print the number of hill numbers less than it. If it is not a hill number, print -1. 

Input

Input will start with a single line giving the number of test cases. Each test case will be a single positive integer on a single line, with up to 70 digits. The result will always fit into a 64-bit long. 

Output

For each test case, print -1 if the input is not a hill number. Print the number of hill numbers less than the input value if the input value is a hill number. 

Sample Input

5
10
55
101
1000
1234321

Output for Sample Input

10
55
-1
715
94708
 
给你一个数,问你这个是不是山峰数。所谓山峰数,就是类似于12321这种,但是可以都一样。如果是山峰数,求出比他小的所有的山峰数个数。
 
思路:
数字很大,一看就是数位dp。
dp[i][k][w],表示第i位,为数字k的时候,状态是w的个数。w有3中状态,一种递增,一种递减,一种先递增,后递减。
dp[i][k][w] = sum(dp[i-1][j][p]);

 

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1<<30
#define MOD 1000000007
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pi acos(-1.0)
using namespace std;
const int MAXN = 100;
ll dp[MAXN][10][5];
int digit[MAXN];
char s[MAXN];
int ok(char s[])
{
    int len = strlen(s);
    int flag = 0;
    for(int i = 1; i < len; i++){
        if(s[i] > s[i-1] && flag){
            return 0;
        }
        else if(s[i] < s[i-1] && !flag){
            flag = 1;
        }
    }
    return 1;
}
ll dfs(int len,int w,int ismax,int pa)
{
    if(len == 0)return 1;
    if(!ismax && dp[len][pa][w]){//第i位 为pa数字 状态为w的时候的个数
        return dp[len][pa][w];
    }
    ll ans = 0;
    ll fans = 0;
    int maxv = ismax ? digit[len] : 9;
    for(int i = 0; i <= maxv; i++){
        if(w == 1){
            if(i >= pa){
                ans += dfs(len-1,1,ismax && i == maxv,i);
            }
            else {
                ans += dfs(len-1,3,ismax && i == maxv,i);
            }
        }
        else if(w == 2){
            if(i > pa)continue;
            else {
                ans += dfs(len-1,2,ismax && i == maxv,i);
            }
        }
        else if(w == 3) {
            if(i > pa)continue;
            else {
                ans += dfs(len-1,3,ismax && i == maxv,i);
            }
        }
    }
    if(!ismax)dp[len][pa][w] = ans;
    return ans;
}
void solve()
{
    if(!ok(s)){
        printf("-1\n");
        return ;
    }
    int len = 0;
    memset(dp,0,sizeof(dp));
    for(int i = strlen(s) - 1; i >= 0; i--){
        digit[++len] = s[i] - 0;
    }
    printf("%lld\n",dfs(len,1,1,-1) - 1);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%s",s);
        solve();
    }
    return 0;
}

 

以上是关于codeforces Hill Number 数位dp的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 1560F2 Nearest Beautiful Number (hard version)(二分+数位dp)

假的数论gcd,真的记忆化搜索(Codeforce 1070- A. Find a Number)

Codeforces 628D 数位dp

Educational Codeforces Round 8(D. Magic Numbers(数位DP))

codeforces 628D. Magic Numbers 数位dp

CodeForces - 55D(数位dp,离散化)