题目链接:https://www.luogu.com.cn/problem/P1043
思路:
因为要求分为k个区间,所以依次枚举将区间分为k个,然后枚举左右区间,求出区间的最大,最小值。
注意:数组开两倍。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 105;
ll dp[2][N][N][N] = {0},a[N] = {0};
const ll mod = 10;
const ll inf = 1e16+10;
int n,m;
ll Mod(ll x)
{
x = (x%mod + mod)%mod;
return x;
}
int main(void)
{
scanf("%d%d",&n,&m);
a[0] = 0;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i+n] = a[i];
for(int i=1;i<=n*2;i++) a[i] += a[i-1];
for(int i=1;i<=m;i++)
{
for(int r=i;r<=n*2;r++)
{
for(int l=1;r-l+1>=i;l++)
{
if(i == 1){
dp[1][i][l][r] = Mod(a[r] - a[l-1]);
dp[0][i][l][r] = Mod(a[r] - a[l-1]);
continue;
}
dp[1][i][l][r] = inf;
for(int j=l;j<=r;j++)
{
if(l<=j-1 && r>=j) //这里注意一下,要保证区间是合法的,不然会输出0
dp[1][i][l][r] = min(dp[1][i][l][r],dp[1][i-1][l][j-1]*Mod(a[r] - a[j-1]));
dp[0][i][l][r] = max(dp[0][i][l][r],dp[0][i-1][l][j-1]*Mod(a[r] - a[j-1]));
}
}
}
}
ll mx = 0,mi = inf;
for(int i=1;i<=n;i++)
mx = max(mx,dp[0][m][i][i+n-1]),mi = min(mi,dp[1][m][i][i+n-1]);
printf("%lld\n%lld\n",mi,mx);
return 0;
}