zoukankan      html  css  js  c++  java
  • 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

    划分dp

    把环变链(读入4 3 -1 2变成4 3 -1 2 4 3 -1 2)

    设dp[i][j][k]为把i~j分成k份,各部分内的数字相加,相加所得的k个结果对10取模后再相乘,最终得到的一个数,这个数的最大或最小值。

    dp[i][j][k]=max/min{dp[i][p][k-1]+func(p+1,j)}

    i+k-2<=p<=j-1  func(i,j)=(sum(i,j)%10+10)%10

    (注意有负数取余,这样写:(x%10+10)%10 )

    边界:dp[i][j][1]=func(i,j)

    答案:max/min(dp[i][i+n-1][m])  i=1 to n+1

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    #define N 80
    #define ll long long
    ll f[N][N],g[N][N],a[N],s[N],n,m,emax,emin=0x7fffffff;
    ll get(ll x){
        return x>=0?x%10:10-abs(x)%10;
    }
    int main(){
        freopen("sh.txt","r",stdin);
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i];
        for(int i=1;i<=n<<1;i++) s[i]=get(s[i-1]+a[i]);
        for(int i=0;i<n;i++){
            memset(f,0,sizeof f);
            memset(g,1,sizeof g);//取较大值 注意数据可能导致上溢 
            for(int j=1;j<=n;j++) f[j][1]=g[j][1]=get(s[j+i]-s[i]);
            for(int j=2;j<=m;j++){
                for(int k=j;k<=n;k++){
                    for(int l=1;l<k;l++){
                        f[k][j]=max(f[k][j],f[l][j-1]*(get(s[k+i]-s[l+i])));
                        g[k][j]=min(g[k][j],g[l][j-1]*(get(s[k+i]-s[l+i])));
                    }
                }
            }
            emax=max(emax,f[n][m]);
            emin=min(emin,g[n][m]);    
        }
        cout<<emin<<endl<<emax<<endl;
        return 0;
    }
  • 相关阅读:
    目前阻碍大数据成功的常见问题有哪些
    YII2 的授权(Authorization)
    CCBPM工作流引擎的消息机制与设计
    日志框架实现实时改动,实时生效,详细框架思路(2)
    manacher hihoCoder1032 最长回文子串
    C#.NEt-GDI+中的Pen測试
    Unity3D游戏开发最佳实践20技巧(一)
    Android init.rc文件浅析
    OBIEE开发手冊
    Android Jni层 创建 linux socket 出错问题解决
  • 原文地址:https://www.cnblogs.com/shenben/p/5716024.html
Copyright © 2011-2022 走看看