Gym - 101889E Enigma(数位填数+记忆化)

Posted yzm10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 101889E Enigma(数位填数+记忆化)相关的知识,希望对你有一定的参考价值。

https://cn.vjudge.net/problem/Gym-101889E

 

1??????????????????????????????? 2

10000000000000000000000000000000

 

???????????????????????????????1 2

*

 

?294?? 17

129404

 

 

题意:给出一个数(长度<=1000),某些数位未知,向?填数,使其能被MOD(<=1000)整除且最小(不含前导零)。

利用数位dp思想,从前往后从小到大依次填数,dp[pos][sta]标记当前状态。

往常的数位dp大多表示方案数,这里只需用01表示该状态是否出现过即可,因此便达到了记忆化的效果。

找到的第一个满足条件的数即为最小。

 

#include <bits/stdc++.h>
#define MAX 1005
using namespace std;
typedef long long ll;

int len,MOD;
string s;
int dp[MAX][MAX];
int f;
inline void dfs(int pos,int sta,string ans){
    if(f==1) return;
    if(pos==len){
        if(sta==0){
            f=1;
            cout<<ans<<endl;
        }
        return;
    }
    if(dp[pos][sta]==1) return;
    if(s[pos]==?){
        for(int i=0;i<=9;i++){
            if(pos==0&&i==0) continue;
            if(f==1) return;
            dfs(pos+1,(sta*10+i)%MOD,ans+(char)(i+0));
            if(f==1) return;
        }
    }
    else{
        if(f==1) return;
        dfs(pos+1,(sta*10+s[pos]-0)%MOD,ans+s[pos]);
        if(f==1) return;
    }
    dp[pos][sta]=1;
}
int main(void)
{
    cin>>s>>MOD;
    f=0;len=s.length();
    dfs(0,0,"");
    if(f==0) cout<<"*"<<endl;
    return 0;
}

 

以上是关于Gym - 101889E Enigma(数位填数+记忆化)的主要内容,如果未能解决你的问题,请参考以下文章

Gym101889E. Enigma(bfs+数位)

数位dp——奏响数字数位的美妙乐章

数位DP || Gym 101653RRamp Number

Gym 100418J Lucky tickets(数位dp)

Gym - 100623J Just Too Lucky (数位dp)

poj3208启示录——数位DP