本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

Description

小E同学非常喜欢书法,他听说NOI2013已经开始了,想题一幅“NOI”的字送给大家。

小E有一张非常神奇的纸,纸可以用一个n 行m 列的二维方格矩阵来表示,为了描述方便,我们定义矩阵左下角方格坐标为(1,1) ,右上角方格坐标为(m,n) 。矩阵的每个方格有一个整数的幸运值。在格子上面写字可以增加大家的幸运度,幸运度的大小恰好是所有被笔写到的方格的幸运值之和。现在你要在上面写上 ‘N’,‘O’,‘I’三个字母。

下面给出3个书法字的定义:

1.‘N’由若干(≥3)个边平行于坐标轴的矩形组成,设有K个矩形组成(标号1~K),第i个矩形的左下角方格坐标设为(Li ,Bi) ,右上角坐标设为(Ri ,Ti) ,要求满足:
a)Li<=Ri,Bi<=Ti
b)对任意1<i<=K,有Li=R(i-1)+1
c)对任意3<=i<K,有B(i-1)-1<=Ti<=T(i-1),Bi<=B(i-1);" 
d)B2>B1,T2=T1,B(K-1)=B(K),T(k-1)<T(K)

2.‘O’由一个大矩形A,挖去一个小矩形B得到,这两个矩形的边都平行于坐标轴。设大矩形左下角的方格坐标为(u,v),长为W宽为H,则小矩形B满足左下角方格坐标为(u+1,v+1) ,长W-2 ,宽H-2。要求满足:
a)W>=3,H>=3
b)u>R(K)+1

3.‘I’为3个边平行于坐标轴的从下到上的实心矩形组成,从下到上依次标号为1,2,3,第i 个矩形的左下角格子坐标设为(Pi , Qi ),右上角格子坐标设为(Gi , Hi ),要求满足:
a)Pi<=Gi,Qi<=Hi
b)P1=P3>u+W,G1=G3
c)Q1=H1=Q2-1,H2+1=Q3=H3
d)P1<P2<=G2<G1

下图是一个‘N’,‘O’,‘I’的例子

另外,所有画的图形均不允许超过纸张的边界。现在小E想要知道,他能画出的最大幸运度是多少。

Input

第一行包含两个正整数n和m,分别表示矩阵的行数和列数。
接下来n行,每行有m个整数,第i+1行的第j个数表示格子(j,n-i+1)的幸运值。

Output

输出一个整数T,表示小E能够获得的最大幸运度

Sample Input

【样例输入1】
3 13
1 1 -1 -1 1 -1 1 1 1 -1 1 1 1
1 -1 1 -1 1 -1 1 -1 1 -1 -1 1 -1
1 -1 -1 1 1 -1 1 1 1 -1 1 1 1

【样例输入2】
3 13
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

Sample Output

【样例输出1】
24
【样例输出2】
-20

HINT

正解:DP

解题报告:

  复述一遍要求:

  “N”由三个部分组成:最左边是一个矩形,最右边也是一个矩形,中间部分是若干个矩形,要求横坐标必须连续,同时左下、右上纵坐标不升,并且第一个矩形与最左边的上端齐平,最后一个矩形与最右边的下端齐平。

  “O”必须是一个矩形挖掉了中间,得到的一个宽度只能为1的边框。

  “I”只能是上下两个高为1的全等矩形中间夹一个任意形状的矩形(左右边界必须被严格限制在范围内)。

  三个字母中间需要至少隔开一列。

  别的转移都很好做,就是基础DP。唯独N的中间的转移需要仔细考虑。

  分为从1转来和从2转来两种,首先从1转来的话,只需要从n for到1,固定上界的同时保存后缀最大值,更新即可。

  从2转来的话,预处理一下前缀最大值,即下界固定为j,上界为1到i中的最大值。

  更新的时候,让j从i for到n,直接更新即可。

  最后补充一点就是,只能在9处更新答案,空格可以用两个变量存着。

  细节很多,需要仔细调试...

//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
using namespace std;
typedef long long LL;
const int MAXN = 152;
const int MAXM = 520;
const int inf = (1<<30)-1;
int n,m,xing[MAXN][MAXM],dp[MAXN][MAXN],ans;
int f[2][12][MAXN][MAXN],s[MAXN],blank[MAXM][2];
//f[0、1][type][i][j] inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void upd(int &x,int y){ if(x<y) x=y; } inline void work(){
n=getint(); m=getint(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) xing[i][j]=getint();
int tag=1,last,now; ans=-inf; for(int i=0;i<=m;i++) blank[i][0]=blank[i][1]=-inf;
memset(f,-0x3f,sizeof(f));
for(int lie=1;lie<=m;lie++) {//枚举列
last=tag; tag^=1; blank[lie][0]=blank[lie-1][0]; blank[lie][1]=blank[lie-1][1];
memset(f[tag],-0x3f,sizeof(f[tag]));
s[0]=0; for(int i=1;i<=n;i++) s[i]=s[i-1]+xing[i][lie];//前缀和
//1:the left of N
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++) {
upd(f[tag][1][i][j],s[j]-s[i-1]);
upd(f[tag][1][i][j],f[last][1][i][j]+s[j]-s[i-1]);
} //2:the middle of N
memset(dp,-0x3f,sizeof(dp));
for(int j=1;j<=n;j++) for(int i=1;i<=j;i++) dp[i][j]=max(dp[i-1][j],f[last][2][i][j]);//前缀最大值(下界为j),即下界固定为j,上界为1到i中的最大值
for(int i=1;i<=n;i++) {//这一次上界i,下界为j
now=dp[i-1][i-1];//上一次的下界取值最小要为i-1
//和2相接
for(int j=i;j<=n;j++){//枚举下界
upd(now,dp[i][j]);
upd(f[tag][2][i][j],now);
}
//和1相接
now=-inf;//后缀最大值
for(int j=n;j>=i;j--) {
//now保存的是上界为i,下界为j+1到n的矩阵中的1的最大值
upd(now,f[last][1][i][j+1]);//1和2相接的地方,必须要间隔1。一路往上取max即可
upd(f[tag][2][i][j],now);
}
for(int j=i;j<=n;j++) f[tag][2][i][j]+=s[j]-s[i-1];
} //3:the right of N
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) dp[i][j]=f[last][2][i][j];
for(int j=1;j<=n;j++) for(int i=j;i>=1;i--) upd(dp[i-1][j],dp[i][j]);//后缀max
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++) {
upd(f[tag][3][i][j],dp[i+1][j]+s[j]-s[i-1]);
upd(f[tag][3][i][j],f[last][3][i][j]+s[j]-s[i-1]);
} //N和O中间的空行
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) upd(blank[lie][0],f[last][3][i][j]); //4:the left of O
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][4][i][j]=blank[lie-1][0]+s[j]-s[i-1]; //5:the middle of O
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][5][i][j]=max(f[last][5][i][j],f[last][4][i][j])+xing[i][lie]+xing[j][lie]; //6:the right of O
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][6][i][j]=f[last][5][i][j]+s[j]-s[i-1]; //O和I中间的空行
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) upd(blank[lie][1],f[last][6][i][j]); //7:the left of I
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][7][i][j]=max(f[last][7][i][j],blank[lie-1][1])+xing[i][lie]+xing[j][lie]; //8:the middle of I
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][8][i][j]=max(f[last][8][i][j],f[last][7][i][j])+s[j]-s[i-1]; //9:the right of I
for(int i=1;i<=n;i++)
for(int j=i+2;j<=n;j++)
f[tag][9][i][j]=max(f[last][8][i][j],f[last][9][i][j])+xing[i][lie]+xing[j][lie],ans=max(ans,f[tag][9][i][j]);
}
printf("%d",ans);
} int main()
{
work();
return 0;
}

  

BZOJ3241/UOJ125 [Noi2013]书法家的更多相关文章

  1. 【uoj125】 NOI2013—书法家

    http://uoj.ac/problem/125 (题目链接) 题意 在网格上写“NOI”,每个格子上有一些权值,要求覆盖的权值最大.书写有一些规则. Solution 将“NOI”分成11个部分, ...

  2. [Noi2013]书法家

    来自FallDream的博客,未经允许,请勿转载,谢谢. 小E同学非常喜欢书法,他听说NOI2013已经开始了,想题一幅“NOI”的字送给大家. 小E有一张非常神奇的纸,纸可以用一个n 行m 列的二维 ...

  3. BZOJ 3241: [Noi2013]书法家

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3241 题意: 思路:把每个字母分成三部分,两个字母之间还有空的列,所以我一共设了11个状态 ...

  4. P1398 [NOI2013]书法家

    传送门 就是个普及组 $dp$ 合集,把 $NOI$ 从左到右拆成 $9$ 个部分,每个部分都可以分别 $dp$ 除了 $N$ 的中间部分比较恶心以外其他都还好,自己推一下然后就知道转移,就 $N$ ...

  5. luogu P1398 [NOI2013]书法家

    传送门 注意到\(N\ O\ I\)三个字母都可以从左到右拆成三部分,即\(N=\)一个矩形+一堆矩形+一个矩形,\(O=\)一条+两条横的+一条,\(I=\)两条横的+一个矩形+两条横的,所以可以拆 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. NOI2013 Day2

    NOI2013 Day2 矩阵游戏 题目描述:设矩阵\(F\) 求\(F[n][m](mod (10^9+7))\) solution: 这题可以求通项解决. 设\(X_i=F[i][m]\), \( ...

  8. bzoj 3242: [Noi2013]快餐店 章鱼图

    3242: [Noi2013]快餐店 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 266  Solved: 140[Submit][Status] ...

  9. bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

随机推荐

  1. jetty;linux 目录结构

    [说明]今天看了看jetty这个web容器,上午看基础理论框架知识(后面半点没用到),下午下载了jetty,并且在上面部署了一个war应用,晚上在做eclipses整合jetty的时候出现了问题,下载 ...

  2. EasyNVR摄像机无插件直播如何排查视频广场不在线

    通道配置完成进入视频广场监控通道显示不在线 保证RTSP视频流地址是否可用,推荐用VLC先测试地址是否可用.(注意:软件本身只支持标准的RTSP视频流地址.) 如果是刚配置完需要等大概几秒左右有的网络 ...

  3. C# new和override区别(转)

    override 1. override是派生类用来重写基类中方法的: 2. override不能重写非虚方法和静态方法: 3. override只能重写用virtual.abstract.overr ...

  4. IOS开发复习笔记(4)-TableView

    总结几个TableView常用的代码 1.初始化方面 static string CellIndetifier=@"cellIndetifier"; -(NSInteger)num ...

  5. What are DESC and ASC Keywords?

    What are DESC and ASC Keywords? ASC is the short form for ascending DESC is the short form for desce ...

  6. SQL 排序的N种方法

    一.手工查询得出名次 select * ,select count(*)+1 from T2 where T2.[成绩] > T1.[成绩] as 名次 from T1 结果:  1 2 3 3 ...

  7. jQuery中删除节点方法remove()、detach()、empty()分析

    jQuery中提供了三种删除节点的方法:remove().detach().empty(),本文详细分析这三种方法. 最容易区分的是empty(),该方法严格上属于“清空节点”,即删除其子节点,自身并 ...

  8. ansible的主机变量

    ansible的主机变量(常用):ansible_ssh_host     #用于指定被管理的主机的真实IPansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是2 ...

  9. uwsgi+nginx项目上线

    一.基础环境配置 1.Linux安装配置     1.设置IP地址 [root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 ...

  10. 剑指offer 面试13题

    面试13题: 题目:机器人的运动范围 题:地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子 ...