HDU2089 不要62

中文题意自然不用赘述,原题请戳

解题思路

做的第一道数位DP的题,果然数位DP里面的各种思想都是我曾经没有怎么接触过的。
首先我们将状态分为三种
dp[i][0]:表示从0到长度为i的数的区间里面不包含不吉利的数,且末位不是6的数的个数
dp[i][1]:表示从0到长度为i的数的区间里面不包含不吉利的数,且末位是6的数的个数
dp[i][2]:表示从0到长度为i的数的区间里面不吉利的数的个数。
这样的话我们很容易就能将dp数组预处理出来
dp[i][0]是由前i-1位里面所有的吉利数加上一个不是4的数,还要减去在6后面加上一个2的情况,所以dp[i][0]=dp[i-1][0]*9-dp[i][1]。
dp[i][1]是由前i-1位里面所有的吉利数加上一个6得到;
dp[i][2]是由前i-1位里面所有的不吉利数,加上前i-1位里面所有吉利数加上一个4,以及末位为6的数后面加上一个2得到。
然后这样dp数组我们就预处理出来了,但是现在怎么算从0到一个数x里面有多少个不吉利数呢?
首先对于x,我们将它的每一位分离出来,对于第i位暂且称其为si,对于这一位我们能得到的不吉利数的个数,首先是比它低的位数里面所有数里面的不吉利数乘以si,比如si=5,那么就应该是dp[i-1][2]×5,其实这样我们得到的就已经是0到50000(暂且算这么大吧)里面所有的不吉利数。然后如果这个si比4大,那么必然有比它位数低的所有的数加上一个4所构成的不吉利数,如果这个si大于6的话,同理。那么如果下一位是2,然后si比6大的话,那么就必然出现了62相连。如果此时此刻遍历过的数位里面已经满足了不吉利数的诸多性质,那么剩下的数位不管是什么,就都是不吉利数了。
第一次做数位DP,感觉这个比较新的思想做起来还是挺happy的。

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[10][3], a, b;
void init(){
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 1; i <= 8; 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][1] + dp[i-1][0];
    }
}
int DP(int x){
    bool flag = 0;
    int s[15];
    int idx = 0, sum = x, ans = 0;
    for (; x; x /= 10)
        s[++idx] = (x%10);
    s[idx+1] = 0;
    for (int i = idx; i > 0; i--){
        ans += (dp[i-1][2]*s[i]);
        if (flag) ans += (dp[i-1][0]*s[i]);
        else{
            if (s[i] > 4) ans += dp[i-1][0];
            if (s[i] > 6) ans += dp[i-1][1];
            if (s[i+1] == 6 && s[i] > 2) ans += dp[i][1];
        }
        if (s[i] == 4 || s[i+1] == 6 && s[i] == 2) flag = 1;
    }
    return sum-ans;
}
int main(){
    init();
    while(scanf("%d%d", &a, &b) == 2 && (a+b))
        printf("%d\n", DP(b+1) - DP(a));
    return 0;
}

### HDU OJ 2089 Problem Solution and Description The problem titled "不高兴的津津" (Unhappy Jinjin) involves simulating a scenario where one needs to calculate the number of days an individual named Jinjin feels unhappy based on certain conditions related to her daily activities. #### Problem Statement Given a series of integers representing different aspects of Jinjin's day, such as homework completion status, weather condition, etc., determine how many days she was not happy during a given period. Each integer corresponds to whether specific events occurred which could affect her mood positively or negatively[^1]. #### Input Format Input consists of multiple sets; each set starts with two positive integers n and m separated by spaces, indicating the total number of days considered and types of influencing factors respectively. Following lines contain details about these influences over those days until all cases are processed when both numbers become zero simultaneously. #### Output Requirement For every dataset provided, output should be formatted according to sample outputs shown below: ```plaintext Case k: The maximum times of appearance is x, the color is c. ``` Where `k` represents case index starting from 1, while `x` stands for frequency count and `c` denotes associated attribute like colors mentioned earlier but adapted accordingly here depending upon context i.e., reasons causing unhappiness instead[^2]. #### Sample Code Implementation Below demonstrates a simple approach using Python language to solve this particular challenge efficiently without unnecessary complexity: ```python def main(): import sys input = sys.stdin.read().strip() datasets = input.split('\n\n') results = [] for idx, ds in enumerate(datasets[:-1], start=1): data = list(map(int, ds.strip().split())) n, m = data[:2] if n == 0 and m == 0: break counts = {} for _ in range(m): factor_counts = dict(zip(data[2::2], data[3::2])) for key, value in factor_counts.items(): try: counts[key] += value except KeyError: counts[key] = value max_key = max(counts, key=lambda k:counts[k]) result_line = f'Case {idx}: The maximum times of appearance is {counts[max_key]}, the reason is {max_key}.' results.append(result_line) print("\n".join(results)) if __name__ == '__main__': main() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值