码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷P1043 数字游戏

时间:2017-05-09 23:11:08      阅读:371      评论:0      收藏:0      [点我收藏+]

标签:状态   前缀和   for   前缀   man   --   max   数字   turn   

题意将n个数排位环状,将其分为 k个部分,k个部分 对 10 取模 然后累乘起来,求其最大和最小的值

动态规划 
用 f[ i ][ j ][ k ] 表示将 i--j这几个数 分为 k个部分 能够取到的最大值 
可知状态转移方程 f[ i ][ j ][ k ] = max(f[ i ][ j ][ k ],f[ i ][ l-1 ][ k-1 ] + c[ j ] - c[l-1] 
c 表示前缀和 我们化圈为线 将他的两倍记录下来就行了

 

 

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std ;

int n,m ; 
int f[102][102][10],f2[102][102][10],s[102],c[102] ;

int main() 
{
    scanf("%d%d",&n,&m) ;
    for(int i=1;i<=n;i++) scanf("%d",&s[ i ]),s[n+i] = s[ i ] ;
    for(int i=1;i<=2*n;i++) c[i] = c[i-1]+s[i] ;
    for(int i=1;i<=2*n;i++) 
        for(int j=i;j<=2*n;j++)
        for(int k=1;k<=m;k++) 
        {
            if(k<2) 
            {
                f[i][j][k] = ( (f[i][j-1][k] +s[j] ) %10+10) %10 ;
                f2[i][j][k] = ((f2[i][j-1][k]+s[j])  %10+10) %10 ; 
            }    
            else f[i][j][k] = 1e9 ;
        }    
    for(int i=2;i<=m;i++) 
        for(int j=1;j<=2*n;j++) 
          for(int k=i+j-1;k<=2*n;k++) 
            for(int l=i+j-1;l<=k;l++) 
            {
                f[j][k][i] = min(f[j][k][i],f[j][l-1][i-1] *(((c[k]-c[l-1])%10+10)%10) ) ;
                f2[j][k][i] = max(f2[j][k][i],f2[j][l-1][i-1]*(((c[k]-c[l-1])%10+10)%10 ) );
            }
    int mi = 1e9 ;
    int ma = 0 ;
    for(int i=1;i<=n;i++) 
    {
        mi = min(mi,f[i][i+n-1][m]) ;
        ma = max(ma,f2[i][i+n-1][m]) ;
    }
    printf("%d\n%d",mi,ma) ;
    
    return 0 ;
}

洛谷P1043 数字游戏

标签:状态   前缀和   for   前缀   man   --   max   数字   turn   

原文地址:http://www.cnblogs.com/third2333/p/6833021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!