描述
丁丁最近沉迷於一個數字遊戲之中。這個遊戲看似簡單,但丁丁在研究了許多天之後卻發覺原來在簡單的規則下想要贏得這個遊戲並不那麼容易。遊戲是這樣的,在你面前有一圈整數(一共n個),你要按順序將其分爲m個部分,各部分內的數字相加,相加所得的m個結果對10取模後再相乘,最終得到一個數k。遊戲的要求是使你所得的k最大或者最小。
格式
輸入格式
輸入文件第一行有兩個整數,n(1≤n≤50)和m(1≤m≤9)。以下n行每行有個整數,其絕對值不大於104,按順序給出圈中的數字,首尾相接。
輸出格式
輸出文件有兩行,各包含一個非負整數。第一行是你程序得到的最小值,第二行是最大值。
限制
各個測試點1s
提示
DP!^_^
思路
思路
#include <iostream>
#include <cstring>
#define N 102
#define M 10
#define MAX 0x7f7f7f7f
using namespace std;
int n,m,i,j,k,t,maxx,minn=MAX;
int a[N],sum[N];
int f[N][M],g[N][M];
int main()
{
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>a[i];
a[i+n]=a[i]; //將數組加長一倍,實現破環爲鏈
}
for(i=1;i<=n+n;i++)
sum[i]=sum[i-1]+a[i]; //前i個數的和
for(t=0;t<n;t++) //將環從第t位斷開
{
memset(f,0,sizeof(f));
memset(g,14,sizeof(g));
for(i=1;i<=n;i++) //前i位數
{
f[i+t][1]=g[i+t][1]=((sum[i+t]-sum[t])%10+10)%10; //分成一份
for(j=2;j<=min(i,m);j++) //分成j份
for(k=j-1;k<i;k++)
{
f[i+t][j]=max(f[i+t][j],f[k+t][j-1]*(((sum[i+t]-sum[k+t])%10+10)%10));
g[i+t][j]=min(g[i+t][j],g[k+t][j-1]*(((sum[i+t]-sum[k+t])%10+10)%10));
}
}
maxx=max(f[n+t][m],maxx);
minn=min(g[n+t][m],minn);
}
cout<<minn<<'\n'<<maxx<<endl;
return 0;
}