原题链接:https://vjudge.net/problem/UVA-12105
分类:动态规划
备注:逆向思维
很奇妙,先算最大是几位数,再依次把每个位的数算出来。
#include <bits/stdc++.h>
using namespace std;
const int c[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
const int INF = 0x3f3f3f3f;
int n, m, d[105][3005], f[55][10], kase;
int main(void) {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while(~scanf("%d%d", &n, &m) && n) {
for (int k = 0; k < 10; k++) f[1][k] = k % m;
for (int i = 2; i <= 50; i++)
for (int k = 0; k < 10; k++) {
f[i][k] = (f[i - 1][k] * 10) % m;
}
for (int i = 0; i <= 50; i++)
for (int j = 0; j < m; j++)
d[i][j] = INF;
d[0][0] = 0;
for (int i = 0; i < 50; i++)
for (int j = 0; j < m; j++)
for (int k = 0; k < 10; k++) {
int ni = i + 1, nj = (j * 10 + k) % m;
d[ni][nj] = min(d[ni][nj], d[i][j] + c[k]);
}
int pos = 0;
for (int i = 1; i <= 50; i++)
if (d[i][0] <= n) pos = i;
printf("Case %d: ", ++kase);
if (!pos) puts("-1");
else {
int tj = 0, tag = 0;
for (int i = pos; i > 0; i--) {
for (int k = 9; k >= 0; k--) {
int j = (m + tj - f[i][k]) % m;
// printf("k = %d, j = %d, i = %d, f = %d, d = %d, c = %d\n", k, j, i, f[i][k], d[i - 1][j], c[k]);
if (c[k] + d[i - 1][j] <= n) {
if (k != 0 || tag || i == 1) {
printf("%d", k);
if (!tag) tag = 1;
}
n -= c[k];
tj = j;
break;
}
}
}
puts("");
}
}
return 0;
}