ZOJ - 3962 - Seven Segment Display-17省赛-数位DP

传送门:Seven Segment Display

题意:

求一个给定区间每个数字的消耗值的和;

思路:

数位DP,有点区间和的思想,还有就是这个十六进制,可以用%llx读,还是比较难的;

还有就是到最大的 0xffffffff 后,会从新跳到0,这里要加上两段$solve(ri)+solve(most)-solve(m-1)$;

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
typedef long long ll;
using namespace std;
const ll most = (ll)0xffffffff;
int cost[100] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6, 6, 5, 4, 5, 5, 4};
ll dp[10][100];
int w[10];
ll dfs(ll d, ll sum, bool limit) {
    if (d < 1) return sum;
    if (!limit && dp[d][sum] != -1) return dp[d][sum];
    ll res = 0;
    int top = limit ? w[d] : 15;
    for (int i = 0; i <= top; i++) {
        res += dfs(d - 1, sum + cost[i], limit && i == w[d]);
    }
    if (!limit) dp[d][sum] = res;
    return res;
}
ll solve(ll t) {
    for (int i = 1; i <= 8; i++) {
        w[i] = t % 16;
        t /= 16;
    }
    return dfs(8, 0, true);
}
int main() {
    //freopen("in","r",stdin);
    int t;
    scanf("%d", &t);
    memset(dp, -1, sizeof(dp));
    while (t--) {
        ll n, m, ri;
        scanf("%lld%llx", &n, &m);
        ri = m + n - 1;
        if (ri < most) {
            printf("%lld\n", solve(ri) - solve(m - 1));
        } else {
            printf("%lld\n", solve(ri) + solve(most) - solve(m - 1));
        }
    }
    return 0;
}
View Code

 

posted @ 2018-03-11 17:01  ckxkexing  阅读(147)  评论(0编辑  收藏  举报