P1005 [NOIP2007 提高组] 矩阵取数游戏
前言
今天依旧是不写高精的一天呢!(是的,这位作者又只拿了开 \(LL\) 的 \(\color{yellow}{60}\) 分)
思路描述
看到数据 \(n,m \le 80(30)\) 就知道数组可以任性开,心理有个底后,再来看题目。
状态描述
首先肯定要来一个 \(dp_{i,j}\) 来表示第 \(i\) 次时取第 \(j\) 行的数。
对于每一次放置,我们要考虑到的是之前每一次都取到什么,也就是现在的头和尾分别是哪两个数。
想明白这一点,就可以描述状态了。
\(dp_{i,j,k,t}\) 表示第 \(i\) 次时取第 \(j\) 行的数,对于第 \(j\) 行,它的行首被取了 \(k\) 个数,他的行尾被取了 \(t\) 个数。
由于 $t = i - k $ ,当 \(i,k\) 确定时,\(t\) 也一定唯一,因此可以省略。
状态转移方程
描述出状态了,状态转移方程还会远吗?
显然有
\(dp_{i,j,k} = \max(dp_{i-1,j,k-1}+val(i,j,k),dp_{i-1,j,k}+val(i,j,m-(i-k)+1))\)。
\(val(x,y,z)\) 表示第 \(x\) 次时取位于第 \(y\) 行第 \(z\) 列的数所能获得的得分。
\(\max\) 中的两者分别对应了第 \(i\) 次时,在第 \(j\) 行取队首 \(or\) 队尾的情况。
code
点击查看代码
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
int n,m;
ll a[85][85],dp[85][85][85];
int bas[31];
int main(){
scanf("%d%d",&n,&m);
bas[0]=1;
for(int i=1;i<=30;i++) bas[i]=bas[i-1]*2;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
dp[i][j][i]=dp[i-1][j][i-1]+a[j][i]*bas[i],dp[i][j][0]=dp[i-1][j][0]+a[j][m-i+1]*bas[i];//这两种情况比较特殊,所以单独列。
for(int k=1;k<i;k++){
dp[i][j][k]=max(dp[i-1][j][k-1]+a[j][k]*bas[i],dp[i-1][j][k]+a[j][m-(i-k)+1]*bas[i]);
}
}
}
ll ans=0;
for(int i=1;i<=n;i++){
ll max_num=0;
for(int j=0;j<=m;j++)
max_num=max(max_num,dp[m][i][j]);
ans+=max_num;
}
cout<<ans<<endl;
return 0;
}
ps:经过作者后续习惯性翻翻题解(发现原来区间DP也可以做),以及打输出时的共同启发,发现实际上我们只需要分别枚举对于每一行是的最优解,加起来就可以了。因此状态中表示行的那一维可以省略。然后就有了以下代码。
点击查看代码
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
int n,m;
ll a[85][85],dp[85][85];
int bas[31];
int main(){
scanf("%d%d",&n,&m);
bas[0]=1;
for(int i=1;i<=30;i++) bas[i]=bas[i-1]*2;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
ll ans=0,max_num;
for(int j=1;j<=n;j++){
for(int i=1;i<=m;i++){
dp[i][i]=dp[i-1][i-1]+a[j][i]*bas[i],dp[i][0]=dp[i-1][0]+a[j][m-i+1]*bas[i];
for(int k=1;k<i;k++){
dp[i][k]=max(dp[i-1][k-1]+a[j][k]*bas[i],dp[i-1][k]+a[j][m-(i-k)+1]*bas[i]);
}
}
max_num=0;
for(int i=0;i<=m;i++) max_num=max(max_num,dp[m][i]);
ans+=max_num;
}
cout<<ans<<endl;
return 0;
}
事实上没太大区别,毕竟它的数据范围可以让我任性开(首尾呼应.jpg(确信))。
summary
对于省略维数有了更深刻的理解。
可以用其他维度表示的可以省略。
可以通过分开解决时不需要整体来定义。
\(dp\)百道第六题。(照这个进度可能得一年后在看看有没有百道的希望了QWQ)
加油。
P1005 [NOIP2007 提高组] 矩阵取数游戏的更多相关文章
- [NOIp2007提高组]矩阵取数游戏
OJ题号:洛谷1005 思路: 动态规划. 不难发现每行能够取得的最大值仅与当前行的数据有关,因此本题可以对每行的数据分别DP,最后求和. 设$f_{i,j}$表示左边取$i$个.右边取$j$个的最大 ...
- [NOIP2007] 提高组 洛谷P1005 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 矩阵取数游戏 2007年NOIP全国联赛提高组(dp+高精)
矩阵取数游戏 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description [问题描述]帅帅经常跟 ...
- 洛谷P1005 矩阵取数游戏
P1005 矩阵取数游戏 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次 ...
- NOIP2007 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 洛谷 P1005 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 矩阵取数游戏洛谷p1005
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- P1005 矩阵取数游戏 区间dp 高精度
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n \times mn×m的矩阵,矩阵中的每个元素a_{i,j}ai,j均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n ...
- AC日记——矩阵取数游戏 洛谷 P1005
矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struc ...
- 【洛谷P1005】矩阵取数游戏
矩阵取数游戏 题目链接 每行分别跑一趟区间DP即可 这道题区间DP是非常裸的,按套路来即可 但是很毒瘤的是需要高精度, “我王境泽就是爆零,从这跳下去,也不会用__int128的!” #include ...
随机推荐
- 齐博x1注意事项:再强调严禁用记事本改任何文件
提醒大家,X1任何文件,不要用记事本修改.比如这个用户就改出问题了 导致后台不能升级. 当然这是问题之一, 还有其它意料之外的问题.还没发现. 这个用户做一个测试风格. 配置文件可能是用记事本修改的. ...
- HDFS基础学习
HDFS简介 HDFS即Hadoop Distributed File System,是一个分布式文件系统,用于存储海量数据.一个HDFS集群由一个NameNode和多个DataNode组成. HDF ...
- 「工具推荐」golang 代码可视化工具 go-callvis
「工具推荐」go-callvis go-callvis是相对 以图片的形式展示了go程序的调用关系,这个工具在看复杂项目时尤其有用. 亲测,借助它看祖传golang代码,头痛好多了. 安装 go ge ...
- Go语言核心36讲11
至今为止,我们讲过的集合类的高级数据类型都属于针对单一元素的容器. 它们或用连续存储,或用互存指针的方式收纳元素,这里的每个元素都代表了一个从属某一类型的独立值. 我们今天要讲的字典(map)却不同, ...
- .NET周报【11月第3期 2022-11-22】
国内文章 .NET Conf China 2022 第一批讲师阵容大揭秘!整个期待了! https://mp.weixin.qq.com/s/4p89hhBPw6qv-0OB_T_TOg 目光看过来 ...
- EasyCode全自动单表增删改查!
需要IDEA下载EasyCode插件 准备好三个基础Base类 分页封装基础 package com.gton.io; import lombok.AllArgsConstructor; import ...
- 【PostgreSQL】pgsql编写函数实现批量删除数字结尾的备份表
执行前: 最终代码: CREATE OR REPLACE FUNCTION "ap"."iter_drop_table_bak"() RETURNS " ...
- 【Java SE】Day08 String类、static关键字、Arrays类、Math类
一.String类 1.概述 所有双引号字符串,都是String类的对象 字符串常量,会存在字符串常量池中 2.创建 构造函数--空构造.字符数组.字节(byte ASCII码)数组 3.常用方法-- ...
- 【Java SE进阶】Day12 函数式接口、函数式编程(Lambda表达式)
一.函数式接口介绍 1.概念 仅有一个抽象方法的接口 适用于函数式编程(Lambda使用的接口) 语法糖:方便但原理不变,如for-each是Iterator的语法糖 Lambda≈匿名内部类的语法糖 ...
- Python requests 上传文件(以上传图片为例)
from requests_toolbelt import MultipartEncoderimport requests encoderl = MultipartEncoder( fields = ...