zoukankan      html  css  js  c++  java
  • Codevs 1085 数字游戏

    1085 数字游戏

    2003年NOIP全国联赛普及组

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

    题目描述 Description

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

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

                                      2

                       4                           -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

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

    输出描述 Output Description

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

    样例输入 Sample Input

    4 2

    4

    3

    -1

    2

    样例输出 Sample Output

    7

    81

    数据范围及提示 Data Size & Hint

    en

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=205;
     6 int Min,Max,n,sum[maxn],num[maxn],f[maxn][15],g[maxn][15],m;
     7 void DP(int a[]){
     8     for(int i=1;i<=n;i++)
     9       sum[i]=sum[i-1]+a[i];
    10     for(int i=0;i<=n;i++)
    11       for(int j=0;j<=m;j++)
    12         f[i][j]=0,g[i][j]=0x5f;
    13     for(int i=1;i<=n;i++)
    14       f[i][1]=g[i][1]=(sum[i]%10+10)%10;
    15     for(int j=2;j<=m;j++)
    16       for(int i=j;i<=n;i++)
    17         for(int k=j-1;k<=i-1;k++){
    18             f[i][j]=max(f[i][j],f[k][j-1]*(((sum[i]-sum[k])%10+10)%10));
    19             g[i][j]=min(g[i][j],g[k][j-1]*(((sum[i]-sum[k])%10+10)%10));
    20         }
    21     Min=min(Min,g[n][m]);
    22     Max=max(Max,f[n][m]);
    23 }
    24 int main()
    25 {
    26     Min=0x5f;Max=0;
    27     scanf("%d%d",&n,&m);
    28     for(int i=1;i<=n;i++){
    29         scanf("%d",&num[i]);
    30         num[i+n]=num[i];
    31     }
    32     for(int i=0;i<n;i++)
    33       DP(num+i);
    34     printf("%d
    %d",Min,Max);
    35     return 0;
    36 }

    思路:划分型DP+环形DP  f[i][j]=max(f[i][j],f[k][j-1]*(((sum[i]-sum[k])%10+10)%10))的意义是前k个数划分成j-1份,所以前i个数划分成j份的最大值是k到i的和Mod10 * 前k个数划分成j-1份

  • 相关阅读:
    【校招面试 之 C/C++】第23题 C++ STL(五)之Set
    Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server "xxxxxxx".
    Redhat Linux安装JDK 1.7
    ORA-10635: Invalid segment or tablespace type
    Symantec Backup Exec 2012 Agent for Linux 卸载
    Symantec Backup Exec 2012 Agent For Linux安装
    You must use the Role Management Tool to install or configure Microsoft .NET Framework 3.5 SP1
    YourSQLDba介绍
    PL/SQL重新编译包无反应
    MS SQL 监控数据/日志文件增长
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6394063.html
Copyright © 2011-2022 走看看