hdu4362 dp + 单调队列优化
dp传输方程很easy需要 dp[i][j] = min{dp[i - 1][k] + abs(pos[i][j] -pos[i - 1][j]) + cost[i][j]}
n行m一排 每个传输扫描m二级 干脆n*m*m 至O(10^7) 1500ms,能够暴力一试。姿势不正确就会TLE
事实上加上个内联函数求绝对值,同一时候赋值时候不使用min(a, b) 用G++交 就能够水过
正解是:由于每一个转移都是从上一层全部的状态開始转移。将上一层的状态依据pos排序
对当前状态的pos进行讨论,其坐标轴左边的点dp[i][j] = dp[i - 1][k] - pos][i - 1][k]+ pos[i][j] + cost[i][j]
对其坐标轴右边的点便是 dp[i][j] = dp[i - 1][k]+ pos][i - 1][k] - pos[i][j] + cost[i][j]。 pos][i][j]
和 cost[i][j]是常数。
维护一个lans[i],表示上一层0 ~ i位置的dp[i - 1][k] - pos][i - 1][k]最小值。 和一个rans[i],表示上一层i ~ (m - 1)位置的dp[i - 1][k] + pos][i - 1][k]最小值
二分当前状态的pos,若为p。比較左边lans[p - 1]与右边lans[p]的最小值就可以
//#pragma comment(linker, "/STACK:102400000,102400000")
//HEAD
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm> #include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <cstdlib> using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//STL
#define PB push_back
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s) #define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)
#define ALL(c) (c).begin(), (c).end()
#define SZ(V) (int)V.size()
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
#define sqr(x) x * x
typedef long long LL;
typedef vector <int> VI;
typedef unsigned long long ULL;
const double eps = 1e-10;
const LL MOD = 1e9 + 7; using namespace std; const int maxn = 1010;
const int INF = 0x3f3f3f3f; int dp[55][maxn], n, m, x;
int lm[maxn], rm[maxn], lans[maxn], rans[maxn]; struct Node{
int pos, cost;
int lval, rval;
bool operator <(const Node& a) const
{
return pos < a.pos;
}
}a[55][maxn]; void init(int u)
{ REP(j, m)
{
a[u][j].lval = dp[u][j] - a[u][j].pos;
a[u][j].rval = dp[u][j] + a[u][j].pos;
}
sort(a[u], a[u] + m);
CLR(lm, INF), CLR(rm, INF);
int s = 0, e = 0;
lans[0] = lm[0] = a[u][0].lval, rans[m - 1] = rm[0] = a[u][m - 1].rval;
FF(j, 1, m)
{
Node &v = a[u][j];
if (v.lval > lm[e]) lm[++e] = v.lval;
else
{
while (e >= 0 && v.lval < lm[e]) --e;
lm[++e] = v.lval;
}
lans[j] = lm[0];
}
s = e = 0;
FED(j, m - 2, 0)
{
Node &v = a[u][j];
if (v.rval > rm[e]) rm[++e] = v.rval;
else
{
while (e >= 0 && v.rval < rm[e]) --e;
rm[++e] = v.rval;
}
rans[j] = rm[0];
}
} int main()
{
int T;
RI(T);
while (T--)
{
RIII(n, m, x);
REP(i, n) REP(j, m) RI(a[i][j].pos);
REP(i, n) REP(j, m) RI(a[i][j].cost);
REP(j, m) dp[0][j] = abs(x - a[0][j].pos) + a[0][j].cost;
FE(i, 1, n - 1)
{
init(i - 1);
REP(j, m)
{
int p = lower_bound(a[i - 1], a[i - 1] + m, a[i][j]) - a[i - 1];
// cout << "position "<< p << endl;
int lmin = INF, rmin = INF;
if (p) lmin = lans[p - 1] + a[i][j].pos + a[i][j].cost;
if (p < m) rmin = rans[p] - a[i][j].pos + a[i][j].cost;
// cout << "rans[p]: " << rans[p] << endl;
// cout << "lmin: " <<lmin << "rmin: " << rmin << endl;
dp[i][j] = min(lmin, rmin);
}
}
int ans = INF;
REP(j, m) ans = min(dp[n - 1][j], ans);
cout << ans << endl;
}
return 0;
}
这是水过的 1109ms
//#pragma comment(linker, "/STACK:102400000,102400000")
//HEAD
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm> #include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <cstdlib> using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//STL
#define PB push_back
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s) #define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)
#define ALL(c) (c).begin(), (c).end()
#define SZ(V) (int)V.size()
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
#define sqr(x) x * x
typedef long long LL;
typedef vector <int> VI;
typedef unsigned long long ULL;
const double eps = 1e-10;
const LL MOD = 1e9 + 7; using namespace std; const int maxn = 1010;
const int INF = 0x3f3f3f3f; inline int ABS(int x) {if (x < 0) return -x; return x; }
int pos[55][maxn], cost[55][maxn];
int dp[55][maxn]; int main()
{
int T, n, m, x;
RI(T);
while (T--)
{
RIII(n, m, x);
REP(i, n) REP(j, m) RI(pos[i][j]);
REP(i, n) REP(j, m) RI(cost[i][j]);
REP(i, m)
dp[0][i] = ABS(x - pos[0][i]) + cost[0][i];
FE(i, 1, n - 1)
REP(j, m)
{
int t = INF;
REP(k, m)
{
// dp[i][j] = min(dp[i][j], dp[i - 1][k] + ABS(pos[i][j] - pos[i - 1][k]));
int x = dp[i - 1][k] + ABS(pos[i][j] - pos[i - 1][k]);
if (x < t)
t = x;
}
dp[i][j] = t + cost[i][j];
}
int ans = INF;
REP(i, m) ans = min(ans, dp[n - 1][i]);
WI(ans);
}
return 0;
}
版权声明:本文博主原创文章,博客,未经同意不得转载。
hdu4362 dp + 单调队列优化的更多相关文章
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- 1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)
这道题吗= =首先解决了我多年以来对仙人掌图的疑问,原来这种高大上的东西原来是这个啊= = 然后,看到这种题,首先必须的就是缩点= = 缩点完之后呢,变成在树上找最长路了= =直接树形dp了 那么那些 ...
- Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)
题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...
- P3084 [USACO13OPEN]照片Photo (dp+单调队列优化)
题目链接:传送门 题目: 题目描述 Farmer John has decided to assemble a panoramic photo of a lineup of his N cows ( ...
- Codeforces 445A Boredom(DP+单调队列优化)
题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...
- bzoj 1855 dp + 单调队列优化
思路:很容易写出dp方程,很容易看出能用单调队列优化.. #include<bits/stdc++.h> #define LL long long #define fi first #de ...
- 股票交易(DP+单调队列优化)
题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...
- Luogu 2627 修建草坪 (动态规划Dp + 单调队列优化)
题意: 已知一个序列 { a [ i ] } ,求取出从中若干不大于 KK 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...
- 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces
题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...
随机推荐
- Java 小样例:图书馆课程设计(Java 8 版)
用 Java 模拟一个图书馆.包含创建图书.创建读者.借书.还书.列出全部图书.列出全部读者.列出已借出的图书.列出过期未还的图书等功能. 每一个读者最多仅仅能借 3 本书,每一个书最多仅仅能借 3 ...
- Storm-0.9.2-incubating源代码编译打包
近期遇到一些同学询问Storm-0.9.2-incubating源代码编译打包的问题,现将编译步骤说明例如以下: 1.凝视掉project各pom文件里关于maven插件(maven-gpg-plug ...
- 《Nginx文件类型错误解析漏洞--攻击演练》 (转)
今天看书看到其中提到的一个漏洞,那就是Nginx+PHP的服务器中,如果PHP的配置里 cgi.fix_pathinfo=1 那么就会产生一个漏洞.这个配置默认是1的,设为0会导致很多MVC框架(如T ...
- xamarin跨平台iOS、Android 与Windows
http://xamarin.csdn.net/ Xamarin是一个行动App开发平台,提供跨平台开发能力,开发人员透过Xamarin开发工具与程序语言,即可开发出iOS.Android 与Wind ...
- hadoop日志分析
一.项目要求 本文讨论的日志处理方法中的日志,仅指Web日志.事实上并没有精确的定义,可能包含但不限于各种前端Webserver--apache.lighttpd.nginx.tomcat等产生的用户 ...
- Windows phone 8 学习笔记(1) 触控输入
原文:Windows phone 8 学习笔记(1) 触控输入 Windows phone 8 的应用 与一般的Pc应用在输入方式上最大的不同就是:Windows phone 8主要依靠触控操作.因此 ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(一) Caching Application Block (高级)
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(一) Caching Application Block (高级) Caching Application Bl ...
- I深搜
<span style="color:#330099;">/* I - 深搜 基础 Time Limit:1000MS Memory Limit:10000KB 64b ...
- leetCode Min Stack解决共享
原标题:https://oj.leetcode.com/problems/min-stack/ Design a stack that supports push, pop, top, and ret ...
- 如何使用 yum 安装/更新/移除 软件
如何使用 yum 安装/更新/移除 软件 一. 建立仓库(repository)和源 a) 拷贝所以相关rpm包到某个目录 b) 执行createrepo /目录/目录/目录/目录 注意:b)中 ...