zoukankan      html  css  js  c++  java
  • 2020 ccpc 网络赛 1012 Xor

    题意:


    数位DP

    首先,为了方便表示,我们将 |x-y|<=K转化为 x+K>=y 且 y+K>=x。

    此时,我们发现,如果用传统的从高位到低位的数位DP,我们无法处理x+K出现进位之后的情况,因此,我们考虑从低位到高位进行DP。

    设F[now][opa][opb][opx][opy][dax][day][opw]为状态数组,

    now 表示当前DP到了哪一位

    opa 表示 x<=A

    opb 表示 y<=B

    opx 表示 x+K<=y

    opy 表示 y+K<=x

    dax 表示 now-1 位时 x+K 是否产生了进位

    day 表示 now-1 位时 y+K 是否产生了进位

    opw 表示 x^y<=w

    之后,我们利用记忆化搜索,每次枚举now这一位上 x y是 0 还是 1 ,然后就可以算出opa等变量在now上的取值。

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 long long F[35][2][2][2][2][2][2][2];
     9 int T,A,B,K,W;
    10 long long dfs(int now,int opa,int opb,int opx,int opy,int dax,int day,int opw)
    11 {
    12     if(F[now][opa][opb][opx][opy][dax][day][opw]!=-1)return F[now][opa][opb][opx][opy][dax][day][opw];
    13     if(now==31)
    14     {
    15         if(opa&&opb&&opb&&(opx||dax)&&(opy||day)&&opw)return F[now][opa][opb][opx][opy][dax][day][opw]=1;
    16         return F[now][opa][opb][opx][opy][dax][day][opw]=0;
    17     }
    18     int daa=(A>>now)&1,dab=(B>>now)&1;
    19     int dak=(K>>now)&1,daw=(W>>now)&1;
    20     F[now][opa][opb][opx][opy][dax][day][opw]=0;
    21     for(int i=0;i<=1;i++)
    22     {
    23         for(int j=0;j<=1;j++)
    24         {
    25             int nopa,nopb,nopx,nopy,ndax,nday,nopw;
    26             nopa=(opa&&i<=daa)||(!opa&&i<daa);
    27             nopb=(opb&&j<=dab)||(!opb&&j<dab);
    28             
    29             nopx=(opx&&((i+dax+dak)&1)>=j)||(!opx&&((i+dax+dak)&1)>j);
    30             ndax=(i+dax+dak)>1;
    31             
    32             nopy=(opy&&((j+day+dak)&1)>=i)||(!opy&&((j+day+dak)&1)>i);
    33             nday=(j+day+dak)>1;
    34             
    35             nopw=(opw&&(i^j)<=daw)||(!opw&&(i^j)<daw);
    36             F[now][opa][opb][opx][opy][dax][day][opw]+=dfs(now+1,nopa,nopb,nopx,nopy,ndax,nday,nopw);
    37         }
    38     }
    39     return F[now][opa][opb][opx][opy][dax][day][opw];
    40 }
    41 int main()
    42 {
    43     scanf("%d",&T);
    44     while(T--)
    45     {
    46         scanf("%d%d%d%d",&A,&B,&K,&W);
    47         memset(F,-1,sizeof(F));
    48         printf("%lld
    ",dfs(0,1,1,1,1,0,0,1));
    49     }
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    人月神话
    Rails 最佳实践
    萧伯纳名言名句大全
    听话,照做,执行,别发挥
    So Good They Can't Ignore You
    谈谈遵守公司作战纪律
    如何让自己有动力去长久地做一件事情
    新架构优化问题总结
    Markdown 入门
    关于代码版本管理的思考和建议
  • 原文地址:https://www.cnblogs.com/liutianrui/p/13723812.html
Copyright © 2011-2022 走看看