• 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份

  • 相关阅读:
    开放平台架构指南
    绝了!起个好标题的9大技巧
    ASP已老,尚能饭否?
    离职,问题就解决了吗?
    什么是草台班子?
    回忆我的第一个软件项目
    Vue3中的Composables组合式函数,Vue3实现minxins
    Vue3中的teleport节点传送
    js中if逻辑过多,常见review优化
    QT安装
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6394063.html
Copyright © 2020-2023  润新知