首页 > 代码库 > BZOJ 1833 数位DP
BZOJ 1833 数位DP
思路:
数位DP
f[i][j][k]表示走到第i位 开头位j 数字k 出现的次数
$f[i][j][k]+=f[i-1][l][k];$
$f[i][j][j]+=base[i]$
calc的时候要有特殊的技巧...(我看题解学会的)
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define int long longint l,r,f[15][10][10],base[15],ans[10];void calc(int m,int fl){ if(!m)return; int p=1,len=0; for(;10*p<=m;len++,p*=10); for(int i=1;i<=len;i++) for(int j=1;j<=9;j++) for(int k=0;k<=9;k++) ans[k]+=fl*f[i][j][k]; for(int j=1;j<m/p;j++) for(int k=0;k<=9;k++) ans[k]+=fl*f[len+1][j][k]; ans[m/p]+=fl*(m%p+1),m%=p,p/=10; for(int i=len;i;i--){ for(int j=0;j<m/p;j++) for(int k=0;k<=9;k++) ans[k]+=fl*f[i][j][k]; ans[m/p]+=fl*(m%p+1),m%=p,p/=10; }}signed main(){ scanf("%lld%lld",&l,&r),base[1]=1; for(int i=2;i<=13;i++)base[i]=base[i-1]*10; for(int i=1;i<=13;i++) for(int j=0;j<=9;j++){ for(int k=0;k<=9;k++) for(int l=0;l<=9;l++) f[i][j][k]+=f[i-1][l][k]; f[i][j][j]+=base[i]; } calc(l-1,-1),calc(r,1); for(int i=0;i<=9;i++){ printf("%lld",ans[i]); if(i!=9)putchar(‘ ‘); }}
BZOJ 1833 数位DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。