zoukankan      html  css  js  c++  java
  • BZOJ 4521 CQOI2016 * 数位dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4521

    题意概述:给出一个区间[L,R],统计区间中满足:1、4,8不同时出现;2、至少有3个相邻的相同数字 的数字个数。10^10<=L<R<10^11.

    实际上要想个状态方程和转移很好想,只是细节和答案就有点。。。。

    简单来说,设f(i,x,y,0/1/2,0/1)表示第i位上的数是x,第i-1位上的数是y,4,8没有出现过 / 4出现过 / 8出现过,有/无三个相邻的相同数字的数字数量。

    转移的时候f(1,x,y,0/1/2,0/1)可以直接暴力初始化,然后转移过程中对方程后两个位置上的状态讨论即可(分为之前就是这样和之前不是这样但是这一步变成了这样两种)。

    计算答案的时候从高到低考虑,同时注意当前确定下来的数里面4,8出现的情况以及有无相邻的三个数字,以加上限制或者增加更新范围。

    最后说一点建议L那个位置特判一下否则很惨。。。。

    然后循环的时候上界不要写错了,不要脑子不知道发生了什么把10写成了9之类的耗掉了1h,不要问我怎么知道的!!!!!

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<vector>
    11 #include<cctype>
    12 using namespace std;
    13 typedef long long LL;
    14 
    15 LL L,R,f[13][10][10][3][2];
    16 
    17 void dp()
    18 {
    19     for(int x=0;x<10;x++)
    20     for(int y=0;y<10;y++){
    21         f[1][x][y][0][0]=x!=4&&x!=8&&y!=4&&y!=8?1:0;
    22         f[1][x][y][1][0]=(x==4||y==4)&&x!=8&&y!=8?1:0;
    23         f[1][x][y][2][0]=(x==8||y==8)&&x!=4&&y!=4?1:0;
    24     }
    25     for(int i=2;i<=10;i++)
    26     for(int x=0;x<10;x++){
    27         for(int y=0;y<10;y++)
    28         for(int z=0;z<10;z++){
    29             if(x!=4&&x!=8&&(x!=y||x!=z)) f[i][x][y][0][0]+=f[i-1][y][z][0][0];
    30             if(x!=8&&(x!=y||x!=z)) f[i][x][y][1][0]+=f[i-1][y][z][1][0];
    31             if(x==4&&(x!=y||x!=z)) f[i][x][y][1][0]+=f[i-1][y][z][0][0];
    32             if(x!=4&&(x!=y||x!=z)) f[i][x][y][2][0]+=f[i-1][y][z][2][0];
    33             if(x==8&&(x!=y||x!=z)) f[i][x][y][2][0]+=f[i-1][y][z][0][0];
    34             if(x!=4&&x!=8) f[i][x][y][0][1]+=f[i-1][y][z][0][1];
    35             if(x!=8) f[i][x][y][1][1]+=f[i-1][y][z][1][1];
    36             if(x==4) f[i][x][y][1][1]+=f[i-1][y][z][0][1];
    37             if(x!=4) f[i][x][y][2][1]+=f[i-1][y][z][2][1];
    38             if(x==8) f[i][x][y][2][1]+=f[i-1][y][z][0][1];
    39         }
    40         if(x!=4&&x!=8) f[i][x][x][0][1]+=f[i-1][x][x][0][0];
    41         if(x!=8) f[i][x][x][1][1]+=f[i-1][x][x][1][0];
    42         if(x!=4) f[i][x][x][2][1]+=f[i-1][x][x][2][0];
    43     }
    44 }
    45 LL calc(LL A)
    46 {
    47     int n[15]={0},cnt=0;
    48     n[cnt++]=A%10,A/=10;
    49     while(A) n[cnt++]=A%10,A/=10;
    50     LL re=0;
    51     for(int x=1;x<n[10];x++)
    52     for(int y=0;y<10;y++)
    53         re+=f[10][x][y][0][1]+f[10][x][y][1][1]+f[10][x][y][2][1];
    54     int x=n[10];
    55     int ok=0,p4=x==4,p8=x==8;
    56     for(int i=10;i>=1;i--){
    57         for(int y=0;y<n[i-1]+(i==1);y++){
    58             if(y==4&&p8||y==8&&p4) continue;
    59             re+=f[i][x][y][0][1];
    60             if(!p8) re+=f[i][x][y][1][1];
    61             if(!p4) re+=f[i][x][y][2][1];
    62             if(ok||x==y&&x==n[i+1]){
    63                 re+=f[i][x][y][0][0];
    64                 if(!p8) re+=f[i][x][y][1][0];
    65                 if(!p4) re+=f[i][x][y][2][0];
    66             }
    67         }
    68         x=n[i-1],p4|=(x==4),p8|=(x==8);
    69         if(n[i-1]==n[i]&&n[i]==n[i+1]) ok=1;
    70         if(p4&&p8) break;
    71     }
    72     return re;
    73 }
    74 int check(LL x)
    75 {
    76     int n[15]={0},cnt=0,p4=0,p8=0,ok=0;
    77     n[cnt++]=x%10,x/=10;
    78     while(x) n[cnt++]=x%10,x/=10;
    79     for(int i=0;i<cnt;i++){
    80         p4|=n[i]==4,p8|=n[i]==8;
    81         if(p4&&p8) return 0;
    82         if(i>1&&n[i]==n[i-1]&&n[i]==n[i-2]) ok=1;
    83     }
    84     return ok;
    85 }
    86 int main()
    87 {
    88     cin>>L>>R;
    89     dp();
    90     cout<<calc(R)-calc(L)+check(L)<<'
    ';
    91     return 0;
    92 }
  • 相关阅读:
    命令模式
    责任链模式
    代理模式
    享元模式
    195 Tenth Line
    test命令
    read命令
    echo命令
    java反射
    http状态码
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8562653.html
Copyright © 2011-2022 走看看