ZOJ

传送门: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
",solve(ri)-solve(m-1));
        }
        else
        {
            printf("%lld
",solve(ri)+solve(most)-solve(m-1));
        }
    }
    return 0;    
}
原文地址:https://www.cnblogs.com/ckxkexing/p/8544752.html