题目链接:http://exam.upc.edu.cn/problem.php?cid=1326&pid=7
题意:给你一个可能存在错误的加法等式,问最少删除多少列能使等式成立。
eg:
思考:如果某一列已经成立,如上图的1+4=5,他一定可以加到前面最长的成立的等式上,类似于最长上升子序列,不过要n^2扫。
做题时WA了几发,因为没考虑到等式的最高位不能有进位,以及可能某一列一开始没有进位,但是后来由于前面低位的进位导致了自己的进位(这种情况只会出现在初始和为9,低位又进一的情况)。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <bits/stdc++.h> 2 3 const int maxn = 1007; 4 int need[maxn], add[maxn], a[maxn], b[maxn], c[maxn], n; 5 int f[maxn]; 6 7 void read(int *tmp) { 8 for (int i = n; i >= 1; i--) { 9 char tm; 10 scanf(" %c", &tm); 11 tmp[i] = tm - '0'; 12 } 13 } 14 15 int main() { 16 // freopen("in.txt", "r", stdin); 17 while (scanf("%d", &n), n > 0) { 18 read(a), read(b), read(c); 19 int tot = n; 20 for (int i = 1; i <= n; i++) { 21 int tmp = a[i] + b[i]; 22 if (tmp == 9 && c[i] == 0) need[i] = 1; 23 else need[i] = c[i] - tmp % 10; 24 add[i] = (tmp + need[i]) / 10; 25 } 26 while (add[n]) n--; 27 for (int i = 1; i <= n; ++i) { 28 f[i] = -0x3f3f3f3f; 29 if (need[i] == 0) f[i] = 1; 30 for (int j = i - 1; j >= 1; j--) { 31 if (need[i] == add[j] && f[j] >= 0) f[i] = std::max(f[j] + 1, f[i]); 32 } 33 } 34 int ans = 0; 35 for (int i = 1; i <= n; i++) if(add[i] == 0) ans = std::max(ans, f[i]); 36 printf("%d\n", tot - ans); 37 } 38 return 0; 39 }