您的位置:首页 > 其它

zoj 3962 Seven Segment Display 数位dp

2017-04-29 10:54 239 查看
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';
else
tmp=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';
else
c='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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: