#include using namespace std; const int N = 110, M = 10, INF = 0x3f3f3f3f; int n, m; int w[N], s[N]; int f[N][N][M], g[N][N][M]; int get_mod(int x) { return (x % 10 + 10) % 10; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> w[i]; w[i + n] = w[i]; // 破环成链 } for (int i = 1; i <= n * 2; i++) s[i] = s[i - 1] + w[i]; // 预处理前缀和,下标从1开始 memset(f, 0x3f, sizeof f); // 预求最小,先设最大 memset(g, -0x3f, sizeof g); // 预求最大,先设最小 for (int len = 1; len <= n; len++) // 区间DP,先枚举长度 for (int l = 1; l + len - 1 <= n * 2; l++) { // 枚举起点 int r = l + len - 1; // 计算终点 // DP 初始化 // 边界条件是全部划分为k=1,也就是一块时的结果是多少,根据题意,一整块当然就是区间内容相加后对10取模 f[l][r][1] = g[l][r][1] = get_mod(s[r] - s[l - 1]); // 状态转移 for (int k = 2; k <= m; k++) // 枚举每个可以划分成的部分 for (int j = l + k - 2; j <= r - 1; j++) { // 枚举K-1部分时的最后一个终点位置 f[l][r][k] = min(f[l][r][k], f[l][j][k - 1] * get_mod(s[r] - s[j])); g[l][r][k] = max(g[l][r][k], g[l][j][k - 1] * get_mod(s[r] - s[j])); } } // 枚举每个区间长度为n的区间,获取符合长度要求的区间内,划分成m块的最大、最小值 int mx = -INF, mi = INF; for (int i = 1; i <= n; i++) { mx = max(mx, g[i][i + n - 1][m]); mi = min(mi, f[i][i + n - 1][m]); } cout << mi << endl; cout << mx << endl; return 0; }