BZOJ 1026 [SCOI2009]windy数

来源:互联网 发布:java excel按模板导出 编辑:程序博客网 时间:2024/04/19 07:27

题目描述 传送门


原来这就是数位DP,原来做过一道类似的。
主要思路就是设d(i,j)为最高位为ij位有多少个windy数,最后计算答案时要注意细节。
我的好像和大多数人的点不一样,似乎写麻烦了…


代码

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;long long d[10][20],sum[20];int main(){    long long a;    char s1[20],s2[20];    cin>>a;    a--;    sprintf(s1,"%lld",a);    scanf("%s",s2);    int l1=strlen(s1),l2=strlen(s2);    for(int i=0;i<10;i++) d[i][1]=1;    sum[1]=9;    for(int i=2;i<=l2;i++){        for(int j=0;j<=9;j++){            for(int k=0;k<=j-2;k++)                d[j][i]+=d[k][i-1];            for(int k=j+2;k<=9;k++)                d[j][i]+=d[k][i-1];            if(j) sum[i]+=d[j][i];        }    }    int a1=0,a2=0;    for(int i=1;i<=l1-1;i++) a1+=sum[i];    for(int i=1;i<=l2-1;i++) a2+=sum[i];    for(int i=1;i<=s1[0]-'0';i++) a1+=d[i][l1];      for(int i=1;i<=s2[0]-'0';i++) a2+=d[i][l2];    for(int i=l1-1;i>0;i--){        for(int j=s1[l1-i]-'0'+1;j<=9;j++){              if(j>s1[l1-i-1]-2-'0'&&j<s1[l1-i-1]+2-'0') continue;            a1-=d[j][i];        }        if(abs(s1[l1-i]-s1[l1-i-1])<2) break;    }    for(int i=l2-1;i>0;i--){        for(int j=s2[l2-i]-'0'+1;j<=9;j++){              if(j>s2[l2-i-1]-2-'0'&&j<s2[l2-i-1]+2-'0') continue;            a2-=d[j][i];        }        if(abs(s2[l2-i]-s2[l2-i-1])<2) break;    }    cout<<a2-a1<<endl;    return 0;}   
原创粉丝点击