[区间+线性dp]数字游戏
题目描述
丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共\(n\)个),你要按顺序将其分为\(m\)个部分,各部分内的数字相加,相加所得的\(m\)个结果对\(10\)取模后再相乘,最终得到一个数\(k\)。游戏的要求是使你所得的\(k\)最大或者最小。
例如,对于下面这圈数字(\(n=4,m=2\)):
要求最小值时,\(((2−1) mod 10)×((4+3) mod 10)=1×7=7\),要求最大值时,为\(((2+4+3) mod 10)×(−1 mod 10)=9×9=81\)。特别值得注意的是,无论是负数还是正数,对\(10\)取模的结果均为非负值。
丁丁请你编写程序帮他赢得这个游戏。
输入格式
输入文件第一行有两个整数,\(n(1≤n≤50)\)和\(m(1≤m≤9)\)。以下\(n\)行每行有个整数,其绝对值\(≤10^4\),按顺序给出圈中的数字,首尾相接。
输出格式
输出文件有\(2\)行,各包含\(1\)个非负整数。第\(1\)行是你程序得到的最小值,第\(2\)行是最大值。
输入 #1
4 2
4
3
-1
2
输出 #1
7
81
分析
对于这种数据,我这种蒟蒻都能看出来,相信很多dalao看到都能一眼就看出来要把环换成链,这是第一个思想。
然后第二个思想就是取模的问题,由于负数取模应为正,假设这个数为\(n\),我们就可以写一个函数来进行取模运算,也就是\((n\%10+10)\%10\),为什么要这么处理呢,这样就可以把负数取完模变为正,而对于正数就毫无影响,这是一个比较巧妙也重要的处理。
第三个就是前缀和,因为要求和,所以利用前缀和就可以很大的提高效率,思想也会比较明了。
根据dp思想,我们就可以进行状态转移。开一个\(dp\)数组,\(dp[i][j][len]\)代表从\(i\)到\(j\)分成\(len\)段的大小,依次枚举段数,左右端点,和断点,每一次从\(i\)到\(j\)都是由上一个从\(i\)到断点\(c\)分成\(len-1\)段的状态转移而来,转移的过程就是乘上从\(j\)到\(c\)的前缀和取模。我们令取模的函数为\(Mod\),那么状态转移方程如下:(最大值和最小值一样,唯一要注意的是,最大值初始为\(0\),最小值每一次转移要改为\(0x3f3f3f3f\))
f2[l][r][len] = max(f2[l][r][len],f2[l][k][len-1]*Mod(sum[r]-sum[k]));\]
最终再从头到尾扫一遍得结果。
代码
#include<bits/stdc++.h>
using namespace std;
int Mod(int x){//取模优化
return (x%10+10)%10;
}
int n,m;
const int maxn = 105;
int sum[maxn],a[maxn];
int f1[maxn][maxn][10],f2[maxn][maxn][10];
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>a[i];
a[i+n] = a[i];//环变链
}
for(int i=1;i<=2*n;++i){//求前缀和
sum[i] = sum[i-1]+a[i];
}
for(int i=1;i<=2*n;++i){//初始化,分1段时的值
for(int j=1;j<=2*n;++j){
f1[i][j][1] = f2[i][j][1] = Mod(sum[j] - sum[i-1]);
}
}
for(int len=2;len<=m;++len){//枚举分成多少段
for(int l=1;l<=n;++l){//枚举左端点
for(int r=l+len-1;r<=l+n-1;++r){//枚举右端点
f1[l][r][len]=0x3f3f3f3f;//求最小值初始化
for(int k=l+len-2;k<r;++k){//枚举断点
f1[l][r][len] = min(f1[l][r][len],f1[l][k][len-1]*Mod(sum[r]-sum[k]));
f2[l][r][len] = max(f2[l][r][len],f2[l][k][len-1]*Mod(sum[r]-sum[k]));
}
}
}
}
int Max = f2[1][n][m];
int Min = f1[1][n][m];
for(int i=1;i<=n;++i){//从头到尾扫一边
Max = max(Max,f2[i][i+n-1][m]);
Min = min(Min,f1[i][i+n-1][m]);
}
cout<<Min<<endl<<Max<<endl;
//Vocanda
}
[区间+线性dp]数字游戏的更多相关文章
- 洛谷 P1043 数字游戏 区间DP
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 【dp】数字游戏&寒假祭
区间DP 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按 ...
- NOIP2003pj数字游戏[环形DP]
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
- LightOJ1044 Palindrome Partitioning(区间DP+线性DP)
问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...
- codevs 1085 数字游戏 dp或者暴搜
1085 数字游戏 2003年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单 ...
- codevs1085数字游戏(环形DP+划分DP )
1085 数字游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单, ...
- 【线性DP】数字三角形
题目链接 原题链接 题目描述 给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大. 7 3 ...
- XDU 1161 - 科协的数字游戏II
Problem 1161 - 科协的数字游戏II Time Limit: 1000MS Memory Limit: 65536KB Difficulty: Total Submit: 112 ...
随机推荐
- IDEA字节码学习查看神器jclasslib bytecode viewer介绍
转载来自:https://blog.csdn.net/w605283073/article/details/103209221 一.背景 很多人想学习Java反汇编后的字节码,但是一方面缺乏好的资料, ...
- Java实现 蓝桥杯 算法提高 菱形
试题 算法提高 菱形 请编程输出一个菱形.输入为菱形中心到顶点的距离 样例输入 2 样例输出 import java.util.Scanner; public class Main { public ...
- linux性能监控工具nmon生成HTML报告-EasyNmon
一.关于easyNmon说明 为了方便多场景批量性能测试,用golang写了个监控程序,可以通过get url方式启动和停止nmon服务,非常适合配合Loadrunner性能测试框架和jmeter使用 ...
- snowflake原理解析
Snowflake 世界上没有两片完全相同的雪花. - twitter Snowflake原理 这种方案把64-bit分别划分成多段,分开来标示机器.时间等,比如在snowflake中的64-bi ...
- 因为 MongoDB 没入门,我丢了一份实习工作
有时候不得不感慨一下,系统升级真的是好处多多,不仅让我有机会重构了之前的烂代码,也满足了我积极好学的虚荣心.你看,Redis 入门了.Elasticsearch 入门了,这次又要入门 MongoDB, ...
- leetcode 反转链表部分节点
反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m = 2, ...
- MySQL进阶篇(02):索引体系划分,B-Tree结构说明
本文源码:GitHub·点这里 || GitEE·点这里 一.索引简介 1.基本概念 首先要明确索引是什么:索引是一种数据结构,数据结构是计算机存储.组织数据的方式,是指相互之间存在一种或多种特定关系 ...
- Java基础?看完以后再也不惧怕面试了
前言 这篇文章主要是Java基础部分,主要分为3个部分:Java集合.Java多线.JVM:这些东西帮助我面试成功率提升了很多.后面还有中间件Spring.Redis.RocketMQ等等吧,祝愿大家 ...
- 没了IDE,你的Java项目还能Run起来吗~
计算机只能识别机器码0101...编程语言->能执行的机器码 需要经过 预处理->编译->汇编->链接->机器码过程.一个语言处理系统的示意图如下: 编译器 是将源语言程 ...
- MATLAB实例:多元函数拟合(线性与非线性)
MATLAB实例:多元函数拟合(线性与非线性) 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请看:随笔分类 - MATLAB作图 之前写过一篇博 ...