題目(狀態(tài)DP)
丁丁最近沉迷于一個數字游戲之中躬充。這個游戲看似簡單害晦,但丁丁在研究了許多天之后卻發(fā)覺原來在簡單的規(guī)則下想要贏得這個游戲并不那么容易。游戲是這樣的,在你面前有一圈整數(一共n個)所坯,你要按順序將其分為m個部分,各部分內的數字相加挂捅,相加所得的m個結果對10取模后再相乘芹助,最終得到一個數k。游戲的要求是使你所得的k最大或者最小闲先。
例子
例如状土,對于下面這圈數字(n=4,m=2):
4 3 -1 2
當要求最小值時伺糠,((2-1) mod 10)×((4+3) mod 10)=1×7=7声诸,要求最大值時,為((2+4+3) mod 10)×(-1 mod 10)=9×9=81退盯。特別值得注意的是彼乌,無論是負數還是正數,對10取模的結果均為非負值渊迁。
丁丁請你編寫程序幫他贏得這個游戲
輸入描述
輸入文件第一行有兩個整數慰照,n(1≤n≤50)和m(1≤m≤9)。以下n行每行有個整數琉朽,其絕對值不大于104毒租,按順序給出圈中的數字,首尾相接箱叁。
輸出描述
輸出文件有兩行墅垮,各包含一個非負整數。第一行是你程序得到的最小值耕漱,第二行是最大值算色。
樣本輸入
4 2
4
3
-1
2
樣本輸出
7
81
思路
暫不補充……
源程序
#include <stdio.h>
long mx[10][52],mn[10][52],k,sn,sm;
int sum[102],i,j,l,n,m,ro;
int main(void)
{
scanf("%d%d",&n,&m);
sn=2000000000;
sm=0;
for (i=1;i<=n;i++)
{
scanf("%d",&j);
sum[i]=sum[i-1]+j;
sum[i+n]=sum[i];
}
for (i=1;i<=n;i++)
sum[i+n]+=sum[n];
for (ro=0;ro<n;ro++)
{
for (i=1;i<=n;i++)
{
k=((sum[ro+i]-sum[ro])%10+10)%10;
mn[1][i]=k;
mx[1][i]=k;
}
for (i=2;i<=m;i++)
for (j=i;j<=n;j++)
{
mn[i][j]=2000000000;
mx[i][j]=0;
for (l=i-1;l<j;l++)
{
k=((sum[j+ro]-sum[l+ro])%10+10)%10;
if (mx[i-1][l]*k>mx[i][j])
mx[i][j]=mx[i-1][l]*k;
if (mn[i-1][l]*k<mn[i][j])
mn[i][j]=mn[i-1][l]*k;
}
}
if (mn[m][n]<sn)
sn=mn[m][n];
if (mx[m][n]>sm)
sm=mx[m][n];
}
printf("%ld\n%ld\n",sn,sm);
return 0;
}