[区间+线性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 ...
随机推荐
- python常见面试题讲解(十三)字串的连接最长路径查找
输入描述: 输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母. 输出描述: 数据输出n行,输出结果为按照字典序排列的字符串. 示例1 ...
- Java实现 LeetCode 722 删除注释(暴力筛选)
722. 删除注释 给一个 C++ 程序,删除程序中的注释.这个程序source是一个数组,其中source[i]表示第i行源码. 这表示每行源码由\n分隔. 在 C++ 中有两种注释风格,行内注释和 ...
- Java实现 LeetCode 606 根据二叉树创建字符串(遍历树)
606. 根据二叉树创建字符串 你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串. 空节点则用一对空括号 "()" 表示.而且你需要省略所有不影响字符串与原 ...
- Java实现 蓝桥杯 算法训练 大小写转换
算法训练 大小写转换 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 编写一个程序,输入一个字符串(长度不超过20),然后把这个字符串内的每一个字符进行大小写变换,即将大写字母变成小 ...
- Java实现 蓝桥杯 历届试题 矩阵翻硬币
问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬币进行 Q 操作的定义:将所有第 ix 行,第 jy 列的硬币进行翻转. 其 ...
- 【CSS】常用色值
常用颜色: 嫣红(red):#e54d42 桔橙(orange):#f37b1d 明黄(yellow):#fbbd08 橄榄(olive):#8dc63f 森绿(green):#39b54a 天青(c ...
- 转载:windows下安装mac虚拟机(Vmvare+mac)
体验Mac的高效与思想,每个技术人都应该去了解和体验,本文转载自网络,使用Vmvare,虚拟Mac系统 https://blog.csdn.net/qq_31867709/article/detail ...
- 对LinkedList源码的一些个人理解
由于转行的原因,最近打算开始好好学习,昨天看到了部分的LinkedList源码,并且看了一点数据结构的视频,现总结部分自己的心得体会,以供后期给现在的自己拍砖~ 双向链表每一个元素都有数据本身加指向前 ...
- jQuery实现瀑布流布局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 【经验心得】谈一谈我IT行业未来的方向
随着科技的发展,越来越多的入门行业将被淘汰,其实淘汰的不仅仅是工厂.环卫工人.普工这些无技术含量的工作,有一些运维.编辑等低门槛的行业也将被淘汰,这也是我这两年看互联网发展趋势得出来的结论,人类要想发 ...