Gym - 101889E 記憶化搜尋
阿新 • • 發佈:2018-11-05
思維還是太將江華,開始一直想dp,就是這一位餘數固定時取最小的一個字串,但是字串太大,賦值的時候超時,其實根本沒必要存字串,只要記憶化搜尋,看看[pos][res]這個狀態是否能構成就行,這樣的話1000*1000個狀態, 穩穩的,然後貪心從小列舉,第一個可行的一定是最優解。
#include<bits/stdc++.h> using namespace std; const int N=1e3+10; char s[N], ans[N]; int k, n; int dp[N][N]; int dfs(int pos, int res){ if(pos==n) return res==0; int& ret=dp[pos][res]; if(ret!=-1) return ret; if(s[pos]=='?'){ for(int i=0; i<10; i++){ if(!pos&&!i) continue; ans[pos]=i+'0'; ret=dfs(pos+1, (res*10+i)%k); if(ret==1) return ret; } } else{ ans[pos]=s[pos]; ret=dfs(pos+1, (res*10+s[pos]-'0')%k); } return ret; } int main(){ scanf("%s", s); scanf("%d", &k); n=strlen(s); memset(dp, -1, sizeof dp); if(dfs(0,0)==1){ ans[n]=0; for(int i=0; i<n; i++) putchar(ans[i]); puts(""); } else puts("*"); return 0; }