洛谷P2602|bzoj1833 [ZJOI2010]数字计数 数位dp

来源:互联网 发布:windows update 安装 编辑:程序博客网 时间:2024/05/28 19:23

数位dp先预处理啊,然后xjb乱搞一下啊

好吧其实我还是看了一下题解。。一开始弄错了统计的方法。。于是疯狂wa

有关数位dp的文章的话,传送门:http://blog.csdn.net/wust_zzwh/article/details/52100392,当然是这位大犇写的了%%%%(虽然百度也可以找到)

代码(有抄题解嫌疑的我):

//Decision's template#include<cstdio>#include<cstring>#include<iostream>#include<cstdlib>#include<vector>#include<queue>#include<stack>#include<algorithm>#include<string>#include<cmath>#include<map>#include<set>using namespace std;#define DP_maxn 16#define maxn 100000#define INF 10000007#define mod 1000000007#define mst(s,k) memset(s,k,sizeof(s))typedef long long ll;struct Edge{    int from,to,dist;    Edge(int u,int v,int d):from(u),to(v),dist(d){}};ll dp[20][20][20],d[20],ans[20],t[20],g[20],f[20];       /*-------------------------------template End--------------------------------*/void init(){    mst(dp,0);t[1] = 1;for(int i = 0;i<=9;i++) dp[1][i][i]  = 1;for(int i = 2;i<=15;i++) t[i] = t[i-1]*10;for(int i = 2;i<=13;i++){for(int j = 0;j<=9;j++) {for(int k = 0;k<=9;k++){for(int l = 0;l<=9;l++)     dp[i][k][l] += dp[i-1][j][l];dp[i][k][k] += t[i-1];}}}}void solve(ll x,ll *tmp){for(int i = 0;i<=9;i++) tmp[i] = 0;int len = 15;if(!x) {tmp[0] = 1;return ;}while(t[len]>x) len--;for(int i = 1;i<len;i++){for(int j = 1;j<=9;j++){for(int k = 0;k<=9;k++){tmp[k] += dp[i][j][k];}}}int cur = x/t[len];tmp[0]++;for(int i = 1;i<cur;i++)     for(int k = 0;k<=9;k++)        tmp[k] += dp[len][i][k];x%=t[len];tmp[cur] += x+1;for(int i = len-1;i;i--){    cur = x/t[i];    for(int j = 0;j<cur;j++)        for(int k = 0;k<=9;k++)            tmp[k]+=dp[i][j][k];    x%=t[i];    tmp[cur] += x+1;}}ll x,y;int main(){    //freopen("std.in","r",stdin);    //freopen("std.out","w",stdout);    init();    cin>>x>>y;    solve(y,f);    solve(x-1,g);    for(int i = 0;i<9;i++) cout<<f[i]-g[i]<<" ";    cout<<f[9]-g[9]<<endl;    return 0;}