1. 程式人生 > >【每日dp】 Gym - 101889E Enigma 數位dp 記憶化搜索

【每日dp】 Gym - 101889E Enigma 數位dp 記憶化搜索

題意 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 --) #define
debug(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; string
s; 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 記憶化搜索