2020 Multi-University Training Contest 6 1005 Fragrant numbers(区间dp)
题目
http://acm.hdu.edu.cn/showproblem.php?pid=6831
题意
“1145141919” 的无穷串,给出一个n,要求选最少的num,使得前num个数中间添加任意括号、加号、乘号,计算结果等于n。
题解
打表知只需前13位就可构造出除了 3 和 7 之外的所有数,所以可以在前 13 位做区间dp即可。注意初始化应将所有一开始可能的数字组合都预先放好。
dp[i][j][k1 + k2] = dp[i][mid][k1] & dp[mid + 1][j][k2]
dp[i][j][k1 * k2] = dp[i][mid][k1] & dp[mid + 1][j][k2]
#include <bits/stdc++.h> // #include <iostream> // #include <cstring> // #include <string> // #include <algorithm> // #include <cmath> // #include <cstdio> // #include <queue> // #include <stack> // #include <map> // #include <bitset> // #include <set> // #include <vector> // #include <iomanip> #define ll long long #define ull unsigned long long #define met(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for(int i = a; i <= b; ++i) #define bep(i, a, b) for(int i = a; i >= b; --i) #define lowbit(x) (x&(-x)) #define MID (l + r) / 2 #define ls pos*2 #define rs pos*2+1 #define pb push_back #define ios() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) using namespace std; const int maxn = 1e5 + 1010; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const ll mod = 1e9 + 7; const double eps = 1e-6; const double PI = acos(-1); int dp[14][14][5010]; int ans[5010]; string str = "*11451419191145"; int main() { rep(i, 1, 13) { int sum = 0; rep(j, i, 13) { sum = sum*10 + str[j] - '0'; if(sum > 5000) break; dp[i][j][sum] = 1; } } rep(len, 2, 13) { rep(i, 1, 13 - len + 1) { int j = i + len - 1; rep(mid, i, j - 1) { rep(k1, 1, 5000) { if(!dp[i][mid][k1]) continue; rep(k2, 1, 5000) { if(!dp[mid + 1][j][k2]) continue; if(k1 + k2 <= 5000) dp[i][j][k1 + k2] = 1; if(k1 * k2 <= 5000) dp[i][j][k1 * k2] = 1; } } } } } rep(i, 1, 13) { rep(j, 1, 5000) { if(dp[1][i][j] && !ans[j]) ans[j] = i; } } int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); printf("%d\n", ans[n] == 0 ? -1 : ans[n]); } return 0; } /* */