[洛谷1437&Codevs1257]敲砖块<恶心的dp>
题目链接:https://www.luogu.org/problem/show?pid=1437#sub
http://codevs.cn/problem/1257/
不得不说,这个题非常的恶心,在初次拿到题后我的思路是暴力,思索之后我还是只有暴力,想到最后我还是暴力,当然暴力的方法就是智者见智的了;
在看了题解的思路后,我尝试着去打着到题,结果,完美WA掉。。。然后我就WA了接近一周时间,最后浏览了各种博客才勉强A了这道恶心的dp
很多大佬的博客对于这道题的解法都是要转90度然后才定义dp,说实话,我觉得那种方法略偏麻烦,完全可以不处理原图直接dp
对于这道题,第一件事就是要怎么去看这张图
14 15 4 3 23
33 33 76 2
2 13 11
22 23
31
这是题干里的图,当然在看这张图的时候,要稍微换个方式
14 15 4 3 23
33 33 76 2
2 13 11
22 23
31
这张图有没有很熟悉,想起了啥???我反正是想起了dp入门题里面一道类似的三角形的题,不过图倒过来了
当然就算想起来了也没有大用处,因为这不是重点。
把图变成这样主要是为了方便分析滴
我们来定义一个数组吧:(这才是重点)
定义数组dp[i][j][k]表示第i列第j块砖时已经一共取了k块砖 (也可以理解为,第i列取了j块砖且一共去了k块砖)
好了定义出来了我相信这个方程其实也很容易搞出来了,要注意的是我们要从第n列往回找,不要问我为啥,因为不这样找,你的dp数组就会有些地方没有值
动态转移方程
----------------------------------------------------------------------------------------------------------------------------------
-- --
--dp[i][j][k]=max(dp[ i ][ j ][ k ],dp[ i+1 ][ v ][ k-j ]+sum[ j ][ i ]); --
-- --
----------------------------------------------------------------------------------------------------------------------------------
然后我就来解释一下这个动态转移方程
*dp[i+1][v][k-j]中,v是从j-1到m,因为在第i列取了j个砖头,所以第i+1列至少要去j-1个(通过题中条件,取第i,j块必须先取i-1, j+1和i-1,j)
然后在第i列是一共取k个,所以第i+1列肯定是一共取了k-j个
*sum[j][i]是表示从a[1][i]到a[j][i]的值的和。因为你取第i列第j块,肯定是在第i列上要把前j个取完的
把这些个一想通,这题就明了了,一个预处理sum[][],在来个4重循环跑个dp数组就完了
唯一还值得注意就是ans是可能存在dp数组的任何位置,所以一边动态转移,一边要比较ans
题不难,就看细心了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define maxn 55
#define maxm 1300
using namespace std; int n,m,ans;
int f[maxn][maxn][maxm];
int val[maxn][maxn]; int main()
{
scanf("%d%d",&n,&m);
memset(f,-,sizeof(f));
for(int i=;i<=n;i++)
{
for(int j=;j<=n-i+;j++)
{
scanf("%d",&val[i][j]);
val[i][j]+=val[i-][j];
}
}
f[n][][]=val[][n];
for(int i=n-;i>=;i--)
for(int j=;j<=n-i+;j++)
for(int k=j;k<=min(m,(n-i+)*(n-i+)/);k++)
//第i列的时候,最多取了p*(p+1)/2块砖头 p=n-i+1
{
for(int v=max(j-,);v<=n-i;v++)//i+1列最多就n-i块砖
{
if(f[i+][v][k-j]!=-&&f[i+][v][k-j]+val[j][i]>f[i][j][k])
f[i][j][k]=f[i+][v][k-j]+val[j][i];
}
ans=max(ans,f[i][j][k]);
}
printf("%d",ans);
}
[洛谷1437&Codevs1257]敲砖块<恶心的dp>的更多相关文章
- 洛谷 P1437 [HNOI2004]敲砖块 解题报告
P1437 [HNOI2004]敲砖块 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下所示. 1 ...
- 洛谷P1437 [HNOI2004]敲砖块(dp)
题目背景 无 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 ...
- yzoj P2343 & 洛谷 P1437 [HNOI2004]敲砖块
题意 在一个凹槽中放置了N层砖块,最上面的一层油N块砖,从上到下每层一次减少一块砖.每块砖都有一个分值,敲掉这块砖就能得到相应的分值,如图所示. 如果你想敲掉第i层的第j块砖的话,若i=1,你可以直接 ...
- 2018.08.16 洛谷P1437 [HNOI2004]敲砖块(二维dp)
传送门 看起来普通dp" role="presentation" style="position: relative;">dpdp像是有后效性的 ...
- Luogu 1437 [HNOI2004]敲砖块 (动态规划)
Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...
- 洛谷 P2015 二叉苹果树(codevs5565) 树形dp入门
dp这一方面的题我都不是很会,所以来练(xue)习(xi),大概把这题弄懂了. 树形dp就是在原本线性上dp改成了在 '树' 这个数据结构上dp. 一般来说,树形dp利用dfs在回溯时进行更新,使用儿 ...
- 洛谷 P7163 - [COCI2020-2021#2] Svjetlo(树形 dp)
洛谷题面传送门 神仙级别的树形 dp. u1s1 这种代码很短但巨难理解的题简直是我的梦魇 首先这种题目一看就非常可以 DP 的样子,但直接一维状态的 DP 显然无法表示所有情况.注意到对于这类统计一 ...
- 洛谷CF809C Find a car(数位DP)
洛谷题目传送门 通过瞪眼法发现,\(a_{i,j}=(i-1)\text{ xor }(j-1)+1\). 二维差分一下,我们只要能求\(\sum\limits_{i=0}^x\sum\limits_ ...
- 【题解】洛谷P1169 [ZJOI2007] 棋盘制作(坐标DP+悬线法)
次元传送门:洛谷P1169 思路 浙江省选果然不一般 用到一个从来没有听过的算法 悬线法: 所谓悬线法 就是用一条线(长度任意)在矩阵中判断这条线能到达的最左边和最右边及这条线的长度 即可得到这个矩阵 ...
随机推荐
- node--CommonJS
1.CommonJS 1)弥补js没有标准的缺陷 2.Node模块 1)分为核心模块和用户自定义模块 2)我们可以把公共的功能抽离为一个单独的js文件作为一个模块 其中的成员和属性外界无法访问,若要设 ...
- 2,Java中的数据结构
1,字符串(String) ···String为特殊的引用类型,不可变. ···常用实例方法: 获取子串:substring(start, end); 获取索引:indexOf(cha ...
- node中fs模块 - fs.open() fs.read() fs.write() fs.close()
var fs = require('fs') fs.open('./a.txt', 'a+', function(err, fd) { // 打开文件后 创建缓冲区放置数据 ), // 读取多少字节 ...
- python正则表达式之re模块方法介绍
python正则表达式之re模块其他方法 1:search(pattern,string,flags=0) 在一个字符串中查找匹配 2:findall(pattern,string,flags=0) ...
- 进阶之路 | 奇妙的Thread之旅
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 需要已经具备的知识: Thread的基本概念及使用 AsyncTask的基本概念及使用 学习清单: 线程概述 ...
- 基于@vue/cli 的构建项目(3.0)
1.检测node的版本号 注意:1.Vue CLI需要Node.js的版本 8.9+(推荐8.11.0+) 所以在安装Vue CLI之前先看下node的版本 node -v 2.安装@vue/cli ...
- # 爬虫连载系列(1)--爬取猫眼电影Top100
前言 学习python有一段时间了,之前一直忙于学习数据分析,耽搁了原本计划的博客更新.趁着这段空闲时间,打算开始更新一个爬虫系列.内容大致包括:使用正则表达式.xpath.BeautifulSoup ...
- 浅谈Java开发三层架构
三层架构,一般来说就是将整个业务应用划分为:表现层(UI).业务逻辑层(BLL).数据访问层(DAL).区分层次的目的即为了“高内聚,低耦合”的思想. 概念简介 1.表现层(UI):简单来说,就是展现 ...
- 服务器上监控tomcat,如果挂掉则重启
该脚本用于监控tomcat服务器是否可用,如果服务不可用则重启tomcat 略微修改后也可以用于其他服务的监控 monitor.sh 脚本如下 #!/bin/sh # 定义要监控的页面地址 WebUr ...
- Simulink仿真入门到精通(十一) 模块的封装
当用户编写了自定义的S函数或者使用Simulink标准库中的模块搭建子系统后,可以通过封装为其设计显示外观,追加参数对话框. 封装是构建一个以对话框为接口的交互界面的过程,它将复杂的模块逻辑关系隐藏起 ...