Problem E – Enigma(數位dp)
阿新 • • 發佈:2018-12-13
題意:
給一個1000位大數,有些位置用?遮住,給出這個大數的一個1000以內的因子k,求這個大數(多個輸出最小的,沒有輸出*)
解析:
這麼經典的數位dp居然沒想出來。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod=1e9+7;
char str[1009];
int k;
int remind[1009];
int dp[1009][1009];
int main(){
scanf("%s%d",str,&k);
int len=strlen(str);
remind[len-1]=1%k;
for (int i=len-2;i>=0;i--){
remind[i]=remind[i+1]*10%k;
}
memset(dp,-1,sizeof(dp));
dp[len][0]=0;
for(int i=len-1;i>=0;i--){
if(str[i]!='?'){
for(int j=0;j<k;j++){
if(dp[i+1][j]!=-1)
dp[i][(j+(str[i]-'0')*remind[i])%k]=str[ i]-'0';
}
}
else{
for(int j=0;j<k;j++){
if(dp[i+1][j]!=-1)
for(int num=0;num<=9;num++){
if(i==0&&num==0)continue;
int to=(j+num*remind[i])%k;
if(dp[i][to]==-1||dp[i][to]>num)
dp[i][to]=num;
}
}
}
}
if(dp[0][0]==-1)printf("*\n");
else{
int nex=0;
for(int i=0;i<len;i++){
printf("%d",dp[i][nex]);
nex=((nex-dp[i][nex]*remind[i])%k+k)%k;//上面求dp時的逆運算
}
printf("\n");
}
}