【每日dp】 Gym - 101889E Enigma 數位dp 記憶化搜索
阿新 • • 發佈:2018-10-05
題意 cin 數字 stream iostream fine 狀態 bsp tdi
題意:給你一個長度為1000的串以及一個數n 讓你將串中的‘?’填上數字 使得該串是n的倍數而且最小(沒有前導零)
題解:dp,令dp[len][mod]為是否出現過 填到第len位,余數為mod 的狀態(dp=0 or 1)
用記憶化搜索來實現,dfs返回1或0.
如果搜到最後一位並且余數為0,返回1.
如果搜到已經更新過的dp狀態,直接返回0。
將mod作為全局變量,不斷更新mod。 對於每一位 的‘? ’ 暴力枚舉0~9
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> #include<ctime> #include<vector> #include<queue> #include<stack> #include<list> #include<string> using namespace std; #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++) #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --) #definedebug(x) cerr<<#x<<" = "<<(x)<<endl #define mmm(a,b) memset(a,b,sizeof(a)) #define pb push_back typedef double db; typedef long long ll; const int maxn = 1000+5; const int MAXN = (int)3e5 + 7; const int N = (int)3e5 + 7; const int INF = (int)0x3f3f3f3f; //const ll mod = 1e9 + 7; strings; int n; int mod = 0; int dp[maxn][maxn]; int ans[maxn]; bool dfs(int x) { if (x == s.length())return mod==0; if (dp[x][mod] == 1)return 0; if (s[x] == ‘?‘) { int i = 0; if (x == 0) i = 1; for (; i <= 9; i++) { int md = mod; mod *= 10, mod += i, mod %= n,ans[x]=i; if(dfs(x + 1)) return 1; mod = md; } dp[x][mod] = 1; } else { int md = mod; mod *= 10, mod += s[x] - ‘0‘, mod %= n,ans[x]=s[x]-‘0‘; return dfs(x + 1); dp[x][mod] = 1; mod = md; } return 0; } int main() { cin >> s >> n; if (dfs(0)) { int len = s.length(); rep(i, 0, len - 1)cout << ans[i]; } else puts("*"); //cin >> s; } /* */
【每日dp】 Gym - 101889E Enigma 數位dp 記憶化搜索