题目大意:

给出一张大小为 n ∗ m n*m n∗m 的矩阵,每一块都有一个权值 a i , j a_{i,j} ai,j​ ,可以随机选择起点,并且只能向右拐或向前走,不能碰到走过的路或走出图,求走过的路径权值和最大为多少。

数据范围:

1 ≤ n , m ≤ 32 , ∣ a i , j ∣ ≤ 1 0 4 1 \le n,m \le 32 , |a_{i,j}| \le 10^4 1≤n,m≤32,∣ai,j​∣≤104

思路:

转移方程非常阴间。。。
看到数据范围 n , m ≤ 32 n,m \le 32 n,m≤32 发现使用搜索时间上过不去,所以考虑使用 D P DP DP 。
我们可以发现所有合法的路径一定包含一个或两个回环,如图:

所以我们可以先 D P DP DP 求出所有的回环,再将回环拼接在一起就可以了。
可以发现每一个回环的区别有:
1. 1. 1. 顺时针和逆时针(如图2的两个回环)
2. 2. 2. 结束的点(如图1在右下角,图2第一个回环在右下角,第二个回环在左下角)

所以可以设 f x , y , x x , y y , 0 / 3 , 0 / 1 f_{x,y,xx,yy,0/3,0/1} fx,y,xx,yy,0/3,0/1​ 表示这个回环是在左上角为 ( x , y ) (x,y) (x,y) ,右下角为 ( x x , y y ) (xx,yy) (xx,yy) 的矩阵上,且结束点在左上(左下,右上,右下)角,形状为顺时针(逆时针)的最大路径价值和。


如图,以结束点在右上角为例,则可以转移到的图形有三种:
1. 1. 1. 可以由上一个结束点也在这个点的相同回环转移,如图1。
2. 2. 2. 可以由往下缩短一格后再加上此点的回环转移,如图2。
3. 3. 3. 可以由一个回环加上一段横行(竖行)转移,如图3。

所以要先用前缀和记录所有的横行和竖行的权值前缀和,以便 3 3 3 的转移。
并且图形是由小图形到大图形进行转移,所以要枚举这个回环的长和宽来进行 D P DP DP
转移的状态有 8 8 8 种,慢慢仔细打是可以打完的。

对与两个回环相接,可以得出结论:两个回环的方向相反。
之后枚举一个矩形的左上角和右下角,再分别枚举横,纵坐标的分割点,根据回环方向和回环的结束点更新答案就可以了。

D P DP DP 的时间复杂度为 O ( n 4 ) O(n^4) O(n4) ,枚举更新答案的时间复杂度为 O ( n 5 ) O(n ^ 5) O(n5) ,能过。

AC代码

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,a[40][40],ans=-21000000;
int f[40][40][40][40][4][2];
int hang[40][40],lie[40][40];
int Max(int a,int b,int c,int d)
{int tot=max(max(max(a,b),c),d);return tot;
}
int main()
{scanf("%d %d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);hang[i][j]=hang[i][j-1]+a[i][j];lie[i][j]=lie[i-1][j]+a[i][j];for(int k=0;k<=3;k++)for(int l=0;l<=1;l++)f[i][j][i][j][k][l]=a[i][j];ans=max(ans,a[i][j]);}  for(int len1=1;len1<=n;len1++)//DPfor(int len2=1;len2<=m;len2++){if(len1==len2&&len1==1)continue;for(int x=1;x+len1-1<=n;x++)for(int y=1;y+len2-1<=m;y++){int xx=x+len1-1,yy=y+len2-1;f[x][y][xx][yy][0][0]=Max(f[x][y][xx-1][yy][0][0],f[x][y+1][xx][yy][0][0],f[x+1][y][xx][yy][0][0]+a[x][yy],f[x][y][xx][yy-1][3][0]+lie[xx][yy]-lie[x-1][yy]);f[x][y][xx][yy][1][0]=Max(f[x][y][xx-1][yy][1][0],f[x][y][xx][yy-1][1][0],f[x][y+1][xx][yy][1][0]+a[x][y],f[x+1][y][xx][yy][0][0]+hang[x][yy]-hang[x][y-1]);f[x][y][xx][yy][2][0]=Max(f[x+1][y][xx][yy][2][0],f[x][y][xx][yy-1][2][0],f[x][y][xx-1][yy][2][0]+a[xx][y],f[x][y+1][xx][yy][1][0]+lie[xx][y]-lie[x-1][y]);f[x][y][xx][yy][3][0]=Max(f[x+1][y][xx][yy][3][0],f[x][y+1][xx][yy][3][0],f[x][y][xx][yy-1][3][0]+a[xx][yy],f[x][y][xx-1][yy][2][0]+hang[xx][yy]-hang[xx][y-1]);f[x][y][xx][yy][0][1]=Max(f[x][y][xx-1][yy][0][1],f[x][y+1][xx][yy][0][1],f[x][y][xx][yy-1][0][1]+a[x][yy],f[x+1][y][xx][yy][1][1]+hang[x][yy]-hang[x][y-1]);f[x][y][xx][yy][1][1]=Max(f[x][y][xx-1][yy][1][1],f[x][y][xx][yy-1][1][1],f[x+1][y][xx][yy][1][1]+a[x][y],f[x][y+1][xx][yy][2][1]+lie[xx][y]-lie[x-1][y]);           f[x][y][xx][yy][2][1]=Max(f[x+1][y][xx][yy][2][1],f[x][y][xx][yy-1][2][1],f[x][y+1][xx][yy][2][1]+a[xx][y],f[x][y][xx-1][yy][3][1]+hang[xx][yy]-hang[xx][y-1]);f[x][y][xx][yy][3][1]=Max(f[x+1][y][xx][yy][3][1],f[x][y+1][xx][yy][3][1],f[x][y][xx-1][yy][3][1]+a[xx][yy],f[x][y][xx][yy-1][0][1]+lie[xx][yy]-lie[x-1][yy]);}}for(int len1=1;len1<=n;len1++)//枚举 for(int len2=1;len2<=m;len2++){if(len1==len2&&len1==1)continue;for(int x=1;x+len1-1<=n;x++)for(int y=1;y+len2-1<=m;y++){int xx=x+len1-1,yy=y+len2-1;for(int k=0;k<=3;k++)for(int l=0;l<=1;l++)ans=max(ans,f[x][y][xx][yy][k][l]);for(int k=x;k<xx;k++){   ans=max(ans,f[x][y][k][yy][2][0]+f[k+1][y][xx][yy][1][1]);ans=max(ans,f[x][y][k][yy][3][1]+f[k+1][y][xx][yy][0][0]);}    for(int k=y;k<yy;k++){ans=max(ans,f[x][y][xx][k][3][0]+f[x][k+1][xx][yy][2][1]);ans=max(ans,f[x][y][xx][k][0][1]+f[x][k+1][xx][yy][1][0]);}}}printf("%d\n",ans);
}

【GDKOI2013】贪吃蛇 题解相关推荐

  1. P4944 PION贪吃蛇 题解

    本题很水,只能算上中模拟吧. 第一步就是选一个合适的数据结构存储蛇身,毫无疑问deque双端队列是最好的选择,因为这样移动会更方便. 下一步要输入地图找蛇和蛇的头,找蛇头很好找,遍历一遍数组即可,而找 ...

  2. 【XSY2498】贪吃蛇(bfs/dfs)

    题面 Description Input Output Sample Input & Sample Output [样例输入1] 4 5 ##... ..1#@ 432#. ...#. [样例 ...

  3. 贪吃蛇c语言自动寻路,C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!...

    前几天有个同学加我QQ私聊我说他们老师布置了一个贪吃蛇,他不知道怎么写所以来找我求解,我给他简单讲解了思路和一些难点之后他也能够自己独立将项目完成了!考虑到更多同学可能有贪吃蛇上的问题,今天有时间就来 ...

  4. C语言贪吃蛇详解4,c语言贪吃蛇详解4.食物的投放与蛇的变长

    c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...

  5. C语言处理贪吃蛇游戏蛇的长度,c语言贪吃蛇详解4.食物的投放与蛇的变长

    c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...

  6. 用html编写一个贪吃蛇,HTML编写的贪吃蛇代码

    <HTML编写的贪吃蛇代码>由会员分享,可在线阅读,更多相关<HTML编写的贪吃蛇代码(14页珍藏版)>请在人人文库网上搜索. 1.使用表格 var fangxiang;fan ...

  7. 结队-结队编程项目贪吃蛇-项目进度

    导入pygame 目前已经实现贪吃蛇游戏的场景绘制,舞台的尺寸 redColour = pygame.Color(255,0,0) blackColour = pygame.Color(0,0,0) ...

  8. 贪吃蛇计时器怎么编写java_java编写简易贪吃蛇游戏

    本文实例为大家分享了java编写的贪吃蛇源码,供大家参考,具体内容如下 程序共包含以下两个文件: 文件:ShellWin.java import java.awt.Color; import java ...

  9. Java项目:贪吃蛇游戏(java+swing)

    源码获取:博客首页 "资源" 里下载! 功能简介: 贪吃蛇游戏 大嘴鱼洁面类.完成大嘴鱼的界面的绘制: /*** 大嘴鱼洁面类.完成大嘴鱼的界面的绘制.*/ public clas ...

最新文章

  1. python基础之生成器,生成器函数,列表推导式
  2. centos 添加用户
  3. boost::fusion::result_of::as_map用法的测试程序
  4. mysql having in_MySQL having子句
  5. 【第二组】项目冲刺(Beta版本)第一次每日例会 2017/7/18
  6. nb信号和4g信号_NB-IoT的网络如何组成,以及数据如何传输?
  7. linux 配置root环境变量,root用户Linux 环境变量的配置解决(-bash: jps: command not found)有关问题...
  8. 记一次酷派尚锋Y75刷机
  9. Ubuntu20软件商店无法正确加载,解决办法
  10. -1073740791 (0xC0000409)错误,附加内容:qt布局、页面跳转
  11. 【HTTP图片服务器】【项目记录2】:安装、配置MySQL环境
  12. 姓名:海宁(Justine Henin-Hardenne)
  13. VMware虚拟机安装Linux系统(详细版)
  14. 互联网日报 | 3月5日 星期五 | 抖音成为2020欧洲杯官方合作伙伴;携程GMV连续三年全球旅企第一;华为发布好望云服务...
  15. 电影票房多视图可视化(echarts)
  16. [HDCTF2019]bbbbbbrsa
  17. 猛兽来袭——Integral Protocol
  18. vps虚拟服务器主机,vps虚拟服务器主机
  19. 映美Jolimark FP-627K 打印机驱动
  20. 视频教程-Angular+Django前后端分离实战项目开发教程-AngularJS

热门文章

  1. 美国独立IP主机受欢迎的原因是什么?
  2. emacs如何配置彩虹猫模式
  3. 不用找,你想要的家具灯饰类的犀牛rhino模型素材都在这里!
  4. CW2015 报警功能
  5. 前后端分离实现验证码
  6. 【最全面的】71张图详解IP 地址、IP 路由、分片和重组、三层转发、ARP、ICMP
  7. 【信息安全案例】——软件解密技术(以OllyDbg为例)
  8. day54 css页面布局
  9. 74HC595 驱动
  10. 单片机电路元件以及读数方法讲解((贴片)电阻,电容,二极管,蜂鸣器等)