zoj 3962 Seven Segment Display 数位dp

来源:互联网 发布:倾斜摄影数据处理软件 编辑:程序博客网 时间:2024/06/07 15:55

f(n)代表显示0-n之间的数需要的能量的总和

d[pos][sum] 代表从pos开始到最低位所需要的能量

对于超过FFFFFFFF的情况,只可能出现一次,分类讨论一下,在计算就可以了

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <vector>#include <map>#include <cmath>#include <set>#include <queue>using namespace std;const int INF=1e9+10;const double EPS = 1e-10;  typedef long long ll;char s1[10],s2[10],s3[10];ll d[20][100];int cost[16]={6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};int digit[20];ll dfs(int pos,int limit,ll cnt){if(pos==-1)return cnt;if(!limit&&d[pos][cnt]!=-1) return d[pos][cnt];int up=limit?digit[pos]:15;ll ans=0;for(int i=0;i<=up;i++){ans+=dfs(pos-1,limit&&up==i,1LL*cnt+cost[i]);}if(!limit) d[pos][cnt]=ans;return ans;}ll solve(char *c){int pos=0;int len=strlen(c);for(int i=len-1;i>=0;i--){if(isdigit(c[i]))digit[pos++]=c[i]-'0';else digit[pos++]=c[i]-'A'+10;}ll ans=0;ans=dfs(pos-1,1,0);return ans;}ll todec(char *s){ll a1=0;int len=strlen(s);for(int i=0;i<len;i++){int tmp;if(isdigit(s[i]))tmp=s[i]-'0';elsetmp=s[i]-'A'+10;a1=a1*16+tmp;}return a1;}void tohex(ll x,char *s){int k=0;while(x){int tmp=x%16;char c;if(tmp<10)c=tmp+'0';elsec='A'+tmp-10;s[k++]=c;x/=16;}while(k<8) s[k++]='0';reverse(s,s+k);s[k]=0;}int main(){//freopen("out.txt","w",stdout);int t;scanf("%d",&t);memset(d,-1,sizeof(d));ll mx=4294967295;char s4[]="FFFFFFFF";while(t--){ll ans;int t1;scanf("%d %s",&t1,s1);ll a=todec(s1);ll sum1=0,sum2,sum3;if(a>0){tohex(a-1,s1);sum1=solve(s1);}if(a+t1-1>mx){ll b=a+t1-1;tohex(b%mx-1,s3);sum2=solve(s3);sum3=solve(s4);ans=sum3-sum1+sum2;}else{ll b=a+t1-1;tohex(b,s3);sum2=solve(s3);ans=sum2-sum1;}printf("%lld\n",ans);}    return 0;  }


0 0
原创粉丝点击