HDU 2686 (双线程) Matrix
这也是当初卡了很久的一道题
题意:从左上角的格子出发选一条路径到右上角然后再回到左上角,而且两条路径除了起点和终点不能有重合的点。问所经过的格子中的最大和是多少
状态设计:我们可以认为是从左上角出发了两条路径,然后同时到达右下角。容易看出,第k个阶段所有可能到达的格子构成一条斜线而且满足x1 + y1 = x2 + y2 = k + 1
dp[k][x1][x2]表示第k阶段两条路分别到达(x1, y1) (x2, y2)所能取得的最大值(y1 y2根据上面的等量关系来计算),如果x1 = x2表示两条路径汇合于一点了
状态转移方程:
在求解第k阶段最优解时,首先枚举k-1阶段时的状态(x1', x2'),然后向四个方向延伸出(x1, x2)
dp[k][x1][x2] = max{dp[k-1][x1'][x2'] + num[x1][y1] | (x1=x2), dp[k-1][x1'][x2'] + num[x1][y1] + num[x2][y2] | (x1≠x2)}
在循环的过程中可能会出现从一个点延伸的下一个点的情况,即两条路径可能重合,不过不要紧,因为格子里面都是正数,所以得到的最优解一定是两条不重合的路径
优化:
因为两条路径具有任意性,所以不妨规定第一条路在第二条路的下方(或同一水平线),时间从92MS优化到62MS
第k阶段状态的转移只依赖第k-1阶段的状态,可以用滚动数组(由于原来的空间本不大,所以代码中没有实现滚动数组)
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; int dp[][][], num[][], n; bool islegal(int x, int y)
{
return (x>= && x<=n && y>= && y<=n);
} int main(void)
{
#ifdef LOCAL
freopen("2686in.txt", "r", stdin);
#endif int i, j, k, d1, d2, x1, x2, y1, y2;
while(scanf("%d", &n) == )
{
memset(dp, , sizeof(dp));
for(i = ; i <= n; ++i)
for(j = ; j <= n; ++j)
scanf("%d", &num[i][j]); dp[][][] = num[][];
for(k = ; k <= *n-; ++k)
{
for(i = ; i <= k - ; ++i)
for(j = ; j <= i; ++j)
{//枚举两条路径在k-1步时的状态
for(d1 = ; d1 <= ; ++d1)
for(d2 = ; d2 <= ; ++d2)
{//共四个延伸方向
x1 = i + d1, y1 = k + - x1;
x2 = j + d2, y2 = k + - x2;
if(islegal(x1, y1) && islegal(x2, y2))
{
if(x1 == x2)
dp[k][x1][x2] = max(dp[k][x1][x2], dp[k-][i][j] + num[x1][y1]);
else
dp[k][x1][x2] = max(dp[k][x1][x2], dp[k-][i][j] + num[x1][y1] + num[x2][y2]);
}
}
}
}
printf("%d\n", dp[*n-][n][n]);
}
return ;
}
代码君
HDU 2686 (双线程) Matrix的更多相关文章
- HDU 2686 双进程DP
//第一次遇到这种DP,看大牛的博客都是用最大流求解的...dp[k][i][j] 表示走k步,第一条路线横向走了i步,第二条路线横向走了j步,所获得的最大值.. //转移方程也很好想 #includ ...
- HDU 2686 Matrix 3376 Matrix Again(费用流)
HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...
- [Swust OJ 1084]--Mzx0821月赛系列之情书(双线程dp)
题目链接:http://acm.swust.edu.cn/problem/1084/ Time limit(ms): 1000 Memory limit(kb): 65535 Descriptio ...
- hdu1007 平面最近点对(暴力+双线程优化)
突发奇想,用双线程似乎可以优化一些暴力 比如说平面最近点对这个题目,把点复制成2份 一份按照x排序,一份按照y排序 然后双线程暴力处理,一份处理x,一份处理y 如果数据利用x递减来卡,那么由于双线程, ...
- 从微信小程序开发者工具源码看实现原理(三)- - 双线程通信
文章概览: 引言 小程序开发者工具双线程通信的设计 1.on: 用来收集小程序开发者工具触发的事件回调 2.invoke:以api方式调用开发工具提供的基础能力 3.publish:用来向Appser ...
- 微信小程序之结构目录、视图层、双线程模型、生命周期、事件传递冒泡、组件、request、登录授权及支付
结构目录与配置介绍 视图层与基础语法 双线程模型 生命周期 事件.传递和冒泡 组件.自定义组件.组件事件传递页面 Request.路由跳转.本地存储 登录(后端实现) | 授权(后端实现) 支付(后端 ...
- 微信小程序 - 双线程模型
小程序的双线程模型 官方文档给出的双线程模型: 小程序的宿主环境 微信客户端提供双线程去执行wxml,wxss,js文件. 双线程模型 1.上述的渲染层上面运行着wxml文件,渲染层使用是的webvi ...
- 小程序的目录结构/配置介绍/视图层wxml数据绑定/双线程模型/小程序的启动流程
安装好微信小程序开发软件,创建项目 小程序文件结构和传统web对比 结构 传统web 微信小程序 结构 HTML WXML 样式 CSS WXSS 逻辑 Javascript Javascript 配 ...
- Java学习之线程间通信(双线程)
线程间通讯:多个线程在处理同一资源,但是任务不同 练习一:双线程出现线程安全问题,需要使用同步,思考同步代码添加位置需求:银行账户存钱,显示谁在账户存钱了,存了多少钱分析:操作同一银行账户两个不同的操 ...
随机推荐
- POJ 1547
#include<iostream> #include<string> using namespace std; int main() { int length; int hi ...
- proxool
配置database.xml <!--数据源 读写 --> <bean id="dataSourceRW" class="com.elong.ihote ...
- java 如何从配置文件(.properties)中读取内容
1.如何创建.properties文件 很简单,建立一个txt文件,并把后缀改成.properties即可 2.将.properties文件拷入src的根目录下 3..properties文件内容格式 ...
- android真机自动化测试
appium执行用例时报错问题: 问题解析: 一般该种情况都是因为来连接了多个设备,验证办法:cmd->执行adb devices 看结果是否是多个devices ,如果是这个问题,停掉多余设 ...
- java.lang.ClassCastException: sun.jdbc.odbc.JdbcOdbcStatement cannot be cast to java.beans.Statement
当导入的包为:import java.sql.Statement;时,无任何错误 当导入的包为:import java.beans.Statement;时,出错
- asyn4j -- java 异步方法调用框架
asyn4j 是一个java异步方法调用框架,基于消费者与生产者模式.包括了异步方法执行,异步回调执行,异步工作缓存模块.支持Spring. 让我们写异步方法不再写很多的相关多线程代码.用asyn4j ...
- Java-马士兵设计模式学习笔记-建造者模式
一.概述 二.代码 1.Animal.java public interface Animal { public void bark(); } 2.Dog.java public class Dog ...
- DXT纹理压缩
转:http://blog.csdn.net/lhc717/article/details/6802951 我们知道游戏中对于3D物体表面细节的表现最重要的还是靠贴图来实现的,那么越是高分辨率越是真彩 ...
- JS解析json数据
JS解析json数据(如何将json字符串转化为数组) 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...
- Spring整合JUnit4测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring/ap ...