洛谷P1043 数字游戏
Posted third2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1043 数字游戏相关的知识,希望对你有一定的参考价值。
题意将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 数字游戏的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段