2019 ICPC Nanchang Regional Competition C Question And and Pair (Digital dp)

The digital dp of this question is two-dimensional. We can abstract this question as the number of two numbers that satisfy the condition of the question in 0-S. Therefore, we can carry out two-dimensional digital dp. From this question, we find that there is no need to record Prefix status

Just consider whether the two flags are greater than the original number, and the two numbers cannot be both 1, and when i is 1, n cannot be 0.

The final calculated answer is not the whole answer, because there are cases where i <= j, we know that these two must be symmetrical, but i == j is one of them, so we just divide by +1 and then 2.

Be careful when dividing by 2, because the division in the modulus is a little different, so you need to use the inverse element to multiply

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int mod=1e9+7;
ll f[N][2][2];
string s;
string t;
int len;
ll qmi(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)
            res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll dfs(int cur,int p1,int p2){
    if(cur==len){
        return 1;
    }

    auto &x=f[cur][p1][p2];
    if(x!=-1)
        return x;
    int v1=1,v2=1;
    if(p1){
        v1=s[cur]-'0';
    }
    if(p2)
        v2=s[cur]-'0';
    int i,j;
    ll ans=0;
    for(i=0;i<=v1;i++){
        for(j=0;j<=v2;j++){
            if(i==1&&j==1||(i&&s[cur]-'0'==0))
            continue;
            ans=(ans+dfs(cur+1,p1&&(i==v1),p2&&(j==v2)))%mod;
        }
    }
    return x=ans;
}
ll solve(string t){
    s=t;
    len=(int)s.size();
    return dfs(0,1,1);
}
int main(){
    int q;
    cin>>q;
    ll inv=qmi(2,mod-2);
    while(q--){
        memset(f,-1,sizeof f);
        cin>>t;
        printf("%lld\n",(solve(t)+1)*inv%mod);
    }
}
View Code

 

Guess you like

Origin www.cnblogs.com/ctyakwf/p/12742167.html