Description

在一个凹槽中放置了 n 层砖块、最上面的一层有n 块砖,从上到下每层依次减少一块砖。每块砖都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示。

14 15  4  3  23
33 33 76 2
2 13 11
22 23
31

如果你想敲掉第 i 层的第j 块砖的话,若i=1,你可以直接敲掉它;若i>1,则你必须先敲掉第i-1 层的第j 和第j+1 块砖。

你现在可以敲掉最多 m 块砖,求得分最多能有多少。

Input

输入文件的第一行为两个正整数 n 和m;接下来n 行,描述这n 层砖块上的分值a[i][j],满足0≤a[i][j]≤100。

对于 100%的数据,满足1≤n≤50,1≤m≤n*(n+1)/2;

Output

输出文件仅一行为一个正整数,表示被敲掉砖块的最大价值总和。

Sample Input

4 5
2 2 3 4
8 2 7
2 3
49

Sample Output

19

题解

分析题目中的选取条件,我们会发现:
这道题最终解的形态(选中的数字)可以描述成若干个三角形相互连接或重叠,如上图中的红色砖块,由两个蓝色标识的三角形部分重叠而成。
将最终解的形态(选中的数字)的每列最下层点用线画出(图中的蓝线),可以发现:
1、构成的轮廓线是一条锯齿状的折线;
2、轮廓线上的相邻点布局在三角形的相列与相邻行上,即如果从左向右观察列,轮廓线上的点只能从其左列的上方行或下方行连过来;
3、轮廓线上点所在列的上方点一定全部被选中。
则把原问题转化为沟画出重叠三角形的锯齿状轮廓折线,找到一条合法的路径,使得围在轮廓线内的数字代价和最大。
另,根据第 3 点分析,轮廓线上点所在列的上方点一定全部被选中,可将选中的数字压缩到轮廓线上点,问题进一步转化为求轮廓线上点的代价和最大。

算法

1、预处理:设 $cost[i,j]$表示选取第 $i$ 行第 $j$ 个,需要一起选取的其他点的个数。即与这个点同一列,且在这个点之上的点的个数。
2、$sum[i,j]$表示选取第 $i$ 行第 $j$ 个,需要一起选取的其他点的数值和。即与这个点同一列,且在这个点之上的点的数值之和。这样,$cost[]$,$sum[]$分别记录了走到每个格子本列的数字个数与代价和。
3、因为对于任意一列的任意一个数字,转移到它的前提与之前的方案无关,所以满足了$dp$ 的无后效性。 同时当前列必定要由之前的某个最优状态转移过来,所以又满足了最优子结构的性质。故 $DP$ 是可行的。

 //It is made by Awson on 2017.10.31
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std; int n, m;
int mp[][], cnt[][];
int f[][][]; void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) for (int j = ; j <= n-i+; j++) scanf("%d", &mp[i][j]);
for (int i = ; i <= n; i++)
for (int j = ; j <= n-i+; j++) {
if (i- >= ) mp[i][j] += mp[i-][j+];
cnt[i][j] = (i+)/;
}
memset(f, -, sizeof(f));
f[][][] = ; f[][][] = mp[][];
for (int y = ; y <= n; y++)
for (int x = ; x <= n-y+; x++)
for (int k = ; k <= m; k++)
if (f[x][y][k] != -) {
f[x+][y][k+cnt[x+][y]] = Max(f[x+][y][k+cnt[x+][y]], f[x][y][k]+mp[x+][y]);
if (x == ) f[x][y+][k] = Max(f[x][y+][k], f[x][y][k]);
else f[x-][y+][k+cnt[x-][y+]] = Max(f[x-][y+][k+cnt[x-][y+]], f[x][y][k]+mp[x-][y+]);
}
printf("%d\n", f[][n+][m]);
}
int main() {
work();
return ;
}

[HNOI 2004]敲砖块的更多相关文章

  1. Luogu 1437 [HNOI2004]敲砖块 (动态规划)

    Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...

  2. 洛谷 P1437 [HNOI2004]敲砖块 解题报告

    P1437 [HNOI2004]敲砖块 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下所示. 1 ...

  3. [HNOI2004]敲砖块

    题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...

  4. P1437 [HNOI2004]敲砖块

    题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...

  5. 【题解】HNOI2004敲砖块

    题目传送门:洛谷1437 决定要养成随手记录做过的题目的好习惯呀- 这道题目乍看起来和数字三角形有一点像,但是仔细分析就会发现,因为选定一个数所需要的条件和另一个数所需要的条件会有重复的部分,所以状态 ...

  6. 洛谷P1437 [HNOI2004]敲砖块(dp)

    题目背景 无 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 ...

  7. [HNOI2004]打砖块(敲砖块)

    题目:codevs1257.洛谷P1437 题目大意:有一些砖块呈倒三角形状,每块砖敲掉后有一个分数.除第一行外,敲掉一块砖必须先把上面两块砖敲掉.现在你能敲m块砖,求能得到的最大分数. 解题思路:此 ...

  8. yzoj P2343 & 洛谷 P1437 [HNOI2004]敲砖块

    题意 在一个凹槽中放置了N层砖块,最上面的一层油N块砖,从上到下每层一次减少一块砖.每块砖都有一个分值,敲掉这块砖就能得到相应的分值,如图所示. 如果你想敲掉第i层的第j块砖的话,若i=1,你可以直接 ...

  9. [LUOGU1437] 敲砖块

    题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...

随机推荐

  1. JavaScript(第二十五天)【事件绑定及深入】

    事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型),一种是现代事件绑定(DOM2级模型).现代事件绑定在传统绑定上提供了更强大更方便的功能.   一.传统事件绑定的问题 传统事件绑定有内联模型 ...

  2. 【django之权限组件】

    一.需求分析 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,一个角色拥有若干权限.这样,就构造成& ...

  3. Alpha冲刺——Day2

    一.合照 二.项目燃尽图 三.项目进展 图形界面基本完成 接口文档框架完成,接下来将会不断细化填充 登录界面向服务器请求数据进行ing 四.明日规划 1.注册登录接口能够完成 2.研究idea实现获得 ...

  4. 201621123057 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口,interface,implements,方法签名,has-a,Comparable,Comparator. 1.2 尝试 ...

  5. 201621123043 《Java程序设计》第7周学习总结

    1. 本周学习总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件:用户的操作. 事件源:产生事件的组件. 事件监听程序:对事件进行处理的操作所引发的相关 ...

  6. linux下面根据不同的日期创建不同文件,一般用户数据库的备份的shell编程

    [root@www scripts]# vi sh03.sh #!/bin/bash # Program: #  Program creates three files, which named by ...

  7. babel基本用法

    babel-cli babel-cli是本地使用编译js文件 1.安装: cnpm i babel-cli babel-preset-env -D 2.配置packjson: "script ...

  8. 07_Python的控制判断循环语句1(if判断,for循环...)_Python编程之路

    Python的数据类型在前几节我们都简单的一一介绍了,接下来我们就要讲到Python的控制判断循环语句 在现实编程中,我们往往要利用计算机帮我们做大量重复计算的工作,在这样的情况下,需要机器能对某个条 ...

  9. js实现图片(高度不确定)懒加载

    最近一直在弄广告页,由于广告页几乎都是图片拼凑起来的,为了减少服务器压力和带宽,采用图片懒加载方式,但是我们的图片高度又不确定,所以我在网上下载了echo.js自己改了一下. 大体思路是:让首页先加载 ...

  10. 原生Ajax用法——一个简单的实例

    Ajax全名(Asynchronous(异步) JavaScript and XML )是可以实现局部刷新的 在讲AJax之前我们先用简单的实例说一下同步和异步这个概念 /*异步的概念(就是当领导有一 ...