【zoj3962】Seven Segment Display(数位dp)

来源:互联网 发布:sql语言培训学校 编辑:程序博客网 时间:2024/05/24 06:59

记录一个菜逼的成长。。

题目链接
题目大意:
T组数据。
给你一个n,和8位的十六进制数num,每一位的十六进制数都有一个权值,
问[num,num+n-1]的每个数的权值和。

省赛的时候,后面想到了数位dp,但是在想状态的时候,卡在了第二维的定义上。
(其实当时我很想睡觉。orz.还有就是我太菜。
(貌似权值和作为dp的状态很常见,以后注意一下。。这么水的题,我tm竟然现场没想到,菜的想撞墙。

dp[i][j]:=ij
那么接下来就简单了,直接套数位dp的模板,胡乱搞一搞。

#include <bits/stdc++.h>using namespace std;typedef long long LL;int num[] = {6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4},bit[9];LL dp[9][100];LL dfs(int pos,int sum,int limit){    if(pos == -1)return sum;    if(!limit && dp[pos][sum] != -1)return dp[pos][sum];    int ed = (limit ? bit[pos] : 15);    LL ret = 0;    for( int i = 0; i <= ed; i++ ){        ret += dfs(pos-1,sum + num[i],limit && i == ed);    }    if(!limit)dp[pos][sum] = ret;    return ret;}LL solve(LL x){    for( int i = 0; i < 8; i++ ){        bit[i] = x % 16;        x /= 16;    }    return  dfs(7,0,1);}int main(){    memset(dp,-1,sizeof(dp));    int T;scanf("%d",&T);    while(T--){        int n;        LL num;        scanf("%d%llX",&n,&num);        if(num+n-1 <= (LL)4294967295){            printf("%lld\n",solve(num+n-1) - solve(num-1));        }        else {            LL x = num + n - 1;            x %= (LL)4294967296;            printf("%lld\n",solve((LL)4294967295) - solve(num-1) + solve(x));        }    }    return 0;}
0 0