数字游戏

传送门

解法:

此题能很容易想到用区间dp求

因为要最大值与最小值
所以设两个数组maxn[i][j][t],minn[i][j][t]
分别表示 位置i到位置j的数 分成t份和的乘积最大值、最小值

那么
t=1为边界 此时maxn[i][j][1]=minn[i][j][1]=a[i]+a[i+1]+…+a[j]
t>=2时 maxn[i][j][t]=max{maxn[i][k][t-1]+maxn[k+1][j][1]} minn同理

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
const int p=10;
int n,m,a[110],maxn[110][110][11],minn[110][110][11];
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,n)
    {
        scanf("%d",&a[i]);
        a[i+n]=a[i]=(a[i]%p+p)%p;
    }
    rep(i,1,2*n)
        a[i]=((a[i]+a[i-1])%p+p)%p;
    memset(minn,127,sizeof(minn));
    rep(i,1,2*n)
    {
        rep(j,i,2*n)
        {
            minn[i][j][1]=maxn[i][j][1]=((a[j]-a[i-1])%p+p)%p;
        }
    }
    rep(t,2,m)
    {
        rep(i,1,2*n)
        {
            rep(j,i+t-1,2*n)
            {
                rep(k,i+t-2,j-1)
                {
                    maxn[i][j][t]=max(maxn[i][j][t],maxn[i][k][t-1]*maxn[k+1][j][1]);
                    minn[i][j][t]=min(minn[i][j][t],minn[i][k][t-1]*minn[k+1][j][1]);
                }
            }
        }
    }
    rep(i,1,n)
    {
        maxn[0][0][0]=max(maxn[0][0][0],maxn[i][i+n-1][m]);
        minn[0][0][0]=min(minn[0][0][0],minn[i][i+n-1][m]);
    }
    printf("%d
%d
",minn[0][0][0],maxn[0][0][0]);
    return 0;
}

原文地址:https://www.cnblogs.com/MYsBlogs/p/10984823.html