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 + 单调队列优化的更多相关文章

  1. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  2. 1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)

    这道题吗= =首先解决了我多年以来对仙人掌图的疑问,原来这种高大上的东西原来是这个啊= = 然后,看到这种题,首先必须的就是缩点= = 缩点完之后呢,变成在树上找最长路了= =直接树形dp了 那么那些 ...

  3. Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)

    题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...

  4. P3084 [USACO13OPEN]照片Photo (dp+单调队列优化)

    题目链接:传送门 题目: 题目描述 Farmer John has decided to assemble a panoramic photo of a lineup of his N cows ( ...

  5. Codeforces 445A Boredom(DP+单调队列优化)

    题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...

  6. bzoj 1855 dp + 单调队列优化

    思路:很容易写出dp方程,很容易看出能用单调队列优化.. #include<bits/stdc++.h> #define LL long long #define fi first #de ...

  7. 股票交易(DP+单调队列优化)

    题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...

  8. Luogu 2627 修建草坪 (动态规划Dp + 单调队列优化)

    题意: 已知一个序列 { a [ i ] } ,求取出从中若干不大于 KK 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...

  9. 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces

    题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...

随机推荐

  1. EF一次请求公用一个实例

    应用场景: 我们在程序开发时,对数据库的操作是必不可少的部分,常规的做法是直接使用Using()语句块,在用完后立即释放连接资源,这种做法在桌面应用程序中毫无问题,但是在Web程序中,尤其是在当今大数 ...

  2. javaScript滚动新闻

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  3. 从零開始学习OpenCL开发(一)架构

    多谢大家关注 转载本文请注明:http://blog.csdn.net/leonwei/article/details/8880012 本文将作为我<从零開始做OpenCL开发>系列文章的 ...

  4. android 自己定义开关(SwitchButton)

    近期心血来潮,写了一个自己定义仿iPhone的开关. 有须要的同学能够来下载啦.支持点击自己主动滚动,速率能够自己依据须要改动.触摸滚动,大小自己定义,支持改动样式.就不录制动画,就上传了两张图给大家 ...

  5. 黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block 企业库数据库访问模块通过抽象工厂模式,允许用户 ...

  6. osgi实战学习之路:3. osgi分层概念及相互合作demo

    源码下载 分层: modual: 主要作用于包级管理与共享代码 lifecycle: 主要作用于执行期间的模块管理与訪问osgi底层框架 service: 主要作用于多模块之间的相互通信 demo: ...

  7. HDU1698_Just a Hook(线段树/成段更新)

    解题报告 题意: 原本区间1到n都是1,区间成段改变成一个值,求最后区间1到n的和. 思路: 线段树成段更新,区间去和. #include <iostream> #include < ...

  8. c++堆栈实现

    A Stack is a data-structure that You can only add an element to the top of the Stack, andYou can onl ...

  9. Google Protocol Buffers和java字符串处理控制

    大多数的操作码被从夜晚复制.懒得敲. 直接在源代码和测试结果如下. serabuffer.proto档.使用下面的命令来生成java代码. protoc -I=./ --java_out=./ ser ...

  10. window忘记密码怎么办

    net命令   Net User 功能:添加或更改用户帐号或显示用户帐号信息. 格式:net user [username [password | *] [options]] [/domain] ne ...