题目描述

帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(m*n\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数。游戏规则如下:

  1. 每次取数时须从每行各取走一个元素,共n个。经过m次后取完矩阵内所有元素;
  2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
  3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值\(\times 2^i\)*,其中i表示第i次取数(从1开始编号);
  4. 游戏结束总得分为m次取数得分之和。

帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

解析

除了脑残高精度(反正窝用__int128硬生生水了过去,但是考场上不能用啊),是道还行的dp题。

窝的做法比起其它题解的做法low了很多,时间和空间效率都不是十分优秀,而且也似乎有人用了,还比我快(哭。


观察题目,容易发现我们只能对每行分开进行\(dp\),而对每行的\(dp\)实际上就是一个区间\(dp\),从大区间缩小到小区间。

设\(dp[i][l][r][j]\)表示第\(i\)次取数时,第\(j\)行左边界取到\(l\),右边界取到\(r\)时的最优解。

得到状态转移方程:

\[dp[i][l][r][j]=\max\limits_{i \in [1,m],j \in [1,n]} \{dp[i-1][l-1][r][j]+num[j][l-1]*2^i,dp[i-1][l][r+1][j]+num[j][r+1]*2^i\}
\]

如果直接这么写会炸空间。

观察状态转移方程发现一个状态只与它上一个状态有关,于是考虑一个滚动数组优化。

参考代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 101
#define ll __int128
#define INF 0x7ffffffff
using namespace std;
ll dp[2][N][N][N],n,m,a[N][N];//dp[i][l][r][j]表示第i次取数第j行的最大得分,左端点l,右端点r
inline ll read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
inline ll qp(ll a,ll b)//快速幂
{
ll ans=1;
for(;b;b>>=1){if(b&1)ans*=a;a*=a;}
return ans;
}
void print(ll x)//暴躁老哥,在线__int128
{
if(!x) return;
if(x) print(x/10);
putchar(x%10+'0');
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j) a[i][j]=read();
memset(dp,~0x3f,sizeof(dp));
int now=0;
for(int i=1;i<=n;++i) dp[0][1][m][i]=0;//初始化,不细讲
for(int k=1;k<=m;++k){
now^=1;
for(int i=1;i<=n;++i){
for(int l=1;l<=k+1;++l){
ll r=l+m-k-1;
dp[now][l][r][i]=max(dp[now][l][r][i],max(dp[now^1][l-1][r][i]+a[i][l-1]*qp(2,k),dp[now^1][l][r+1][i]+a[i][r+1]*qp(2,k)));
}
}
}
ll ans=0;
for(int i=1;i<=n;++i){
ll maxx=-INF;
for(int l=1;l<=m;++l)、
//寻找每一行的最优解
maxx=max(maxx,max(dp[now][l][l+1][i],dp[now][l+1][l][i]));
//最后一步会出现两种状态,都要统计
ans+=maxx;
}
if(!ans) printf("0\n");
else print(ans);
return 0;
}

P1005 矩阵取数游戏[区间dp]的更多相关文章

  1. P1005 矩阵取数游戏 区间dp 高精度

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n \times mn×m的矩阵,矩阵中的每个元素a_{i,j}ai,j​均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n ...

  2. 1166 矩阵取数游戏[区间dp+高精度]

    1166 矩阵取数游戏 2007年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description [ ...

  3. 洛谷P1005 矩阵取数游戏

    P1005 矩阵取数游戏 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次 ...

  4. [NOIP2007] 提高组 洛谷P1005 矩阵取数游戏

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

  5. 洛谷 P1005 矩阵取数游戏

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

  6. 洛谷 P1005 矩阵取数游戏 (区间dp+高精度)

    这道题大部分时间都在弄高精度-- 还是先讲讲dp吧 这道题是一个区间dp,不过我还是第一次遇到这种类型的区间dp f[i][j]表示取了数之后剩下i到j这个区间的最优值 注意这里是取了i之前和j之后的 ...

  7. 【Luogu】P1005矩阵取数游戏(高精度+DP)

    题目链接 yeah终于过辣! DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值.借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了. 哇终于不怂高精了…… 放上代码. ...

  8. P1005 矩阵取数游戏

    传送门 思路: △ 区间动规 对于每行,有 f [ i ][ j ] 代表取区间 [ i , j ] 的最大值. 然后转移方程我们考虑,对于每一个新的 f [ i ][ j ],有两种情况(下面定义  ...

  9. P1005 矩阵取数游戏(动态规划+高精度)

    题目链接:传送门 题目大意: 给定长度为m的数列aj,每次从两端取一个数,得到2k * aj的价值(k为当前的次数,从1开始到m),总共有n行这样的数列,求最大价值总和. 1 ≤ n, m ≤ 80, ...

随机推荐

  1. Vue 项目中的ESlint语法报错问题

    在项目中的""和;经常会报错,真的很纠结,今天看到一个解决方法,可以不用卸载删除 在项目根目录中,新建一个.prettierrc文件,来移除分号,和替换为单引号. { " ...

  2. CentOS 7 搭建 GitLab

    概述 GitLab 是我在日常工作中使用的代码仓库管理系统,它带有非常友好的 Web 界面,并且功能丰富.下面将介绍我在 CentOS 7 上搭建 GitLab 的步骤,以及遇到的一些问题. 关于不同 ...

  3. Linux下安装redis以及常用命令

    https://blog.csdn.net/zgf19930504/article/details/51850594 安装: 1.获取redis资源 wget http://download.redi ...

  4. idea设置创建类的注释模板

    打开settings>>Editor>>File and Code Templates>>Includes>>File Header

  5. QT 源码分析--1

    Ref: http://blog.sina.com.cn/s/blog_6e80f1390100qoc0.html 安装qt之后(我使用的是online自动安装),安装目录下有\5.10.1\Src\ ...

  6. [DevExpress] - 使得 XtraEditors.TextEdit 失去焦点(LostFocus)的方法

    场景 WinForm 应用,使用了 DevExpress.XtraEditors.TextEdit 控件的 KeyPress 和 Leave 事件.期望在 TextEdit 上按下回车键或者当 Tex ...

  7. 《Mysql - Count(*) 的优化》

    一:Count(*) 的实现方式? - 要明确的是,在不同的 MySQL 引擎中,count(*) 有不同的实现方式. - MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) ...

  8. python 之 前端开发( DOM操作)

    11.47 DOM操作 查找节点: 11.471 直接查找 document.getElementById //根据ID获取唯一一个标签 document.getElementsByClassName ...

  9. 从零开始学Flask框架-007

    Flash消息 from flask import flash 渲染Flash消息,在基模板base.html中引入get_flashed_messages() {% extends "bo ...

  10. TZOJ1299: 畅通工程

    #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #i ...