140.数字游戏

1085 数字游戏

 

2003年NOIP全国联赛普及组

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
题目描述 Description

丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k。游戏的要求是使你所得的k最大或者最小。

例如,对于下面这圈数字(n=4m=2):

                                  2

                                            -1

                                 3

当要求最小值时,((2-1) mod 10)×((4+3) mod 10)=1×7=7,要求最大值时,为((2+4+3) mod 10)×(-1 mod 10)=9×9=81。特别值得注意的是,无论是负数还是正数,对10取模的结果均为非负值。

丁丁请你编写程序帮他赢得这个游戏。

输入描述 Input Description

输入文件第一行有两个整数,n1≤n≤50)和m1≤m≤9)。以下n行每行有个整数,其绝对值不大于104,按顺序给出圈中的数字,首尾相接。

输出描述 Output Description

输出文件有两行,各包含一个非负整数。第一行是你程序得到的最小值,第二行是最大值。

样例输入 Sample Input

4 2

4

3

-1

2

样例输出 Sample Output

7

81

数据范围及提示 Data Size & Hint

en

分类标签 Tags 点此展开 

注意:这里的负数mod 10,是把负数加10,一直加到这个数大于10,再返回x就是了。
代码:
#include< iostream >
using namespace std;
#include< cstdio >
#include< cmath >
#include< cstring >
#include< cstdlib >
#define INFn 51
#define INF 99999999
#define MIN -99999999
#define INFm 10
long long min(long long a,long long b)
{
return a>b?b:a;
}
long long max(long long a,long long b)
{
return a>b?a:b;
}
long long  mod(long long  x)
{
if(x>=0) return x;
else
{
while(x<0)
{
x+=10;
}
return x;
}

}
long long dpmin[INFn][INFm],dpmax[INFn][INFm],sum[INFn];
int num[INFn],n,m;
long long ansmax=MIN,ansmin=INF;
void chuli(int i)
{
if(i==1) return ;
else {
int t=num[n];
for(int i=n-1;i>=1;--i)
num[i+1]=num[i];
num[1]=t;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&num[i]);
for(int i=1;i<=n;++i)
{
chuli(i); 
memset(sum,0,sizeof(sum));
memset(dpmin,0,sizeof(dpmin));
memset(dpmax,0,sizeof(dpmax));
for(int i=1;i<=n;++i)
sum[i]=sum[i-1]+num[i];
for(int i=1;i<=n;++i)
dpmax[i][1]=dpmin[i][1]=mod(sum[i]);
for(int j=2;j<=m;++j)
 for(int i=j;i<=n;++i)
   {
    dpmin[i][j]=INF;dpmax[i][j]=MIN;
 for(int t=j-1;t<=i-1;++t)
     {
      dpmin[i][j]=min(dpmin[i][j],dpmin[t][j-1]*mod(sum[i]-sum[t]));
      dpmax[i][j]=max(dpmax[i][j],dpmax[t][j-1]*mod(sum[i]-sum[t]));
   
 
       }
ansmin=min(ansmin,dpmin[n][m]);
ansmax=max(ansmax,dpmax[n][m]);
}
cout<<ansmin<<endl<<ansmax;
return 0;
}
posted @ 2016-04-08 17:29  csgc0131123  阅读(216)  评论(0)    收藏  举报