-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathcrci07p4.cpp
93 lines (93 loc) · 2.54 KB
/
crci07p4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Ivan Carvalho
// Solution to https://dmoj.ca/problem/crci07p4
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1001;
const int MAXS = 5001;
char entrada[2 * MAXN];
int dp[MAXN][MAXS];
int zeromaisadireita[MAXN];
int N, S;
int calcula(int ini, int fim) {
int val = 0;
int pot = 1;
if (entrada[ini] == '0') ini = zeromaisadireita[ini];
for (int i = fim; i >= ini; i--) {
int digito = entrada[i] - '0';
val += digito * pot;
pot *= 10;
}
return val;
}
int solve(int pos, int resta) {
if (resta < 0) return 1e8;
if (pos == N) {
if (resta == 0) return 0;
return 1e8;
}
if (dp[pos][resta] != -1) return dp[pos][resta];
int best = 1e9;
int comeco = pos;
if (entrada[pos] == '0') comeco = zeromaisadireita[pos];
int limite = pos;
if (entrada[pos] == '0') limite = zeromaisadireita[pos];
while (limite + 1 < N && calcula(pos, limite + 1) <= resta) {
limite++;
}
for (int quebra = comeco; quebra <= limite; quebra++) {
best = min(best, solve(quebra + 1, resta - calcula(pos, quebra)));
}
return dp[pos][resta] = 1 + best;
}
int main() {
scanf("%s", entrada);
N = strlen(entrada);
int pot = 1;
while (entrada[N - 1] != '=') {
int digito = entrada[N - 1] - '0';
S += digito * pot;
pot *= 10;
N--;
}
N--;
for (int i = 0; i < N; i++) {
if (entrada[i] != '0') continue;
zeromaisadireita[i] = i;
while (zeromaisadireita[i] + 1 < N &&
entrada[zeromaisadireita[i] + 1] == '0') {
zeromaisadireita[i]++;
}
}
memset(dp, -1, sizeof(dp));
// printf("%d\n",solve(0,S));
int ini = 0;
int resta = S;
for (; ini < N;) {
if (ini) printf("+");
int best = 1e9, nxt = -1;
int comeco = ini;
if (entrada[ini] == '0') comeco = zeromaisadireita[ini];
int limite = ini;
if (entrada[ini] == '0') limite = zeromaisadireita[ini];
while (limite + 1 < N && calcula(ini, limite + 1) <= resta) {
limite++;
}
for (int fim = comeco; fim <= limite; fim++) {
int cand = solve(fim + 1, resta - calcula(ini, fim));
if (cand < best) {
best = cand;
nxt = fim;
}
}
resta -= calcula(ini, nxt);
for (int i = ini; i <= nxt; i += 1) printf("%c", entrada[i]);
ini = nxt + 1;
}
printf("=%d\n", S);
return 0;
}
n ",S);
return 0;
}