【分析】
典型的区间dp+环形问题处理,首先考虑线性情况的解法,以最大值为例:
f[i][j][k]表示i到j区间使用了k段的最优值
f[i][j][k] = max(f[i][l]+v[l+1][j]) { i+k-1<l<j }
线性能解决之后就直接断环为链,找所有的f[i][i+n-1]的最值就行了
【AC代码】
#include<cstdio>
#define maxn 139
#define INF 2147483647
using namespace std;
int n, m, f[maxn][maxn][39], v[maxn][maxn], a[maxn], maxx, minn = INF, g[maxn][maxn][39];
int max(int a, int b){return a>b?a:b;}
int min(int a, int b){return a<b?a:b;}
int main(){
//freopen("1.in", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i < n+1; i++){
scanf("%d", a+i);
a[n+i] = a[i]; //断环为链
}
for(int i = 1; i < (n<<1)+1; i++){
for(int j = i; j < (n<<1)+1; j++)
v[i][j] = ((v[i][j-1]+a[j])%10+10)%10; //预处理部分
}
for(int i = (n<<1)-1; i > 0; i--)
for(int j = i; j < (n<<1); j++)
g[i][j][1] = f[i][j][1] = v[i][j]; //初始值部分
for(int i = (n<<1)-1; i > 0; i--)
for(int j = i; j < (n<<1); j++){
for(int k = 2; k < m+1; k++){
g[i][j][k] = INF;
for(int l = i+k-1; l < j; l++){
f[i][j][k] = max(f[i][j][k], f[i][l][k-1]*v[l+1][j]);
g[i][j][k] = min(g[i][j][k], g[i][l][k-1]*v[l+1][j]);
}
}
}
for(int i = 1; i < n+1; i++)maxx = max(maxx, f[i][i+n-1][m]);
for(int i = 1; i < n+1; i++)minn = min(minn, g[i][i+n-1][m]);
printf("%d\n%d\n", minn, maxx);
return 0;
}