hdu 5803 Zhu’s Math Problem (2016多校第六场1011)数位dp

对于不等式a+c-b-d我们思考,如果分解成二进制a1+c1-b1-d1>=2的话后面不用看了,同样a1+c1-b1-d1<=-2的话后面不管怎么办都不满足要求,也就是范围在-2~2之间,所以我们直接数位dp即可。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int mod=1000000007;
typedef long long LL;
int dp[66][16][5][5];
LL in[4];
int dfs(int p,int isup,int f1,int f2){
    if(p<0){
        if(f1>0&&f2>=0) return 1;
        return 0;
    }
    if(dp[p][isup][f1+2][f2+2]!=-1) return dp[p][isup][f1+2][f2+2];
    int ans=0;
    int up[4];
    for(int i=0;i<4;i++){
        if(isup&(1<<i)) up[i]=1;
        else up[i]=(in[i]>>p)&1;
    }
    for(int i=0;i<=up[0];i++){
        for(int j=0;j<=up[1];j++){
            for(int f=0;f<=up[2];f++){
                for(int q=0;q<=up[3];q++){
                    if(f1*2+i+f-j-q<=-2) continue;
                    if(f2*2+i+q-j-f<=-2) continue;
                    int w,w1;
                    w=2*f1+i+f-j-q;
                    if(w>2) w=2;
                    w1=2*f2+i+q-j-f;
                    if(w1>2) w1=2;
                    int no=isup;
                    if(i!=up[0]) no|=1<<0;
                    if(j!=up[1]) no|=1<<1;
                    if(f!=up[2]) no|=1<<2;
                    if(q!=up[3]) no|=1<<3;
                    ans+=dfs(p-1,no,w,w1);
                    ans%=mod;
                }
            }
        }
    }
    return dp[p][isup][f1+2][f2+2]=ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        for(int i=0;i<4;i++) scanf("%lld",&in[i]);
        memset(dp,-1,sizeof(dp));
        printf("%d\n",dfs(60,0,0,0));
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值