vijos 1243 生产产品 DP + 单调队列优化
题意:有1个产品,m个步骤编号为1~m。步骤要在n个机器人的手中生产完成。其中,第i个步骤在第j个机器人手中的生产时间给定为$T[i][j]$,切换机器人消耗cost。步骤必须按顺序,同一个机器人不能连续完成超过l个步骤。求完成所有步骤的最短时间是多少。其中$m<=10^5$,$n<=5$,$l<=5*10^4$
思路:这题用DP考虑易得一个转移方程$dp[i][j]=\min^{i-1}_{v=i-L}{(dp[v][x] + sum[i][j] - sum[v][j]) + cost}$其中$sum[i][j]$代表前i步由j完成的时间和
从转移式上来看,j为要转移到的状态,x为出发态,相当于对每个步骤v都做$O(n^2)$的转移,直接暴力枚举的话总复杂度是$O(l·m·n^2)$
当L足够大时,显然这样的算法不够快,可以注意到v的枚举是顺序的,而且$dp[v][x] -sum[v][j]$在给定x和j时也满足单调性的要求,即当$dp[v][x] -sum[v][j]$得到更小的值后,最优值为新得到的值,那么使用二维优先队列维护从x机器人转移到j机器人,范围为L的优先队列,队列存储其划分的位置,这样一来我们可在$O(1)$复杂度内获得L范围内的最小值(队列中元素最多进出一次),优化后复杂度$O(m·n^2)$
/** @Date : 2017-07-19 19:25:11
* @FileName: vijos 1243 单调性优化 DP 双端队列.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; int n, m, cost, l;
int sum[100500][8];
int dp[100500][8]; int main()
{
while(cin >> m >> n >> cost >> l)
{
int x;
for(int i = 1; i <= n; i++)
{
sum[0][i] = 0;
for(int j = 1; j <= m; j++)
{
scanf("%d", &x);
sum[j][i] = sum[j - 1][i] + x;
}
} deque<int >q[8][8];
for(int i = 0; i <= m; i++)
for(int j = 0; j <= n; j++)
dp[i][j] = INF;
for(int j = 0; j <= n; j++)
dp[0][j] = 0;
/*for(int i = 1; i <= n; i++)
for(int k = 1; k <= n; k++)
q[i][k].push_back(0);*/
///////////////////////
for(int i = 0; i <= m; i++)
{
for(int j = 1; j <= n; j++)//删除头不符合条件的
for(int x = 1; x <= n; x++)//from
{
if(j == x)
continue;
while(!q[j][x].empty()
&& i - l > q[j][x].front())
q[j][x].pop_front();
} for(int j = 1; j <= n; j++)//单独考虑j
for(int x = 1; x <= n; x++)//from 从什么方向转移
{
if(j == x)
continue;
int v = 0;
if(!q[j][x].empty())
v = q[j][x].front();
dp[i][j] = min(dp[v][x] - sum[v][j] + sum[i][j] + cost, dp[i][j]);
}
for(int j = 1; j <= n; j++)//删除尾不单调(不最优的)
for(int x = 1; x <= n; x++)//from
{
if(j == x)
continue;
while(!q[j][x].empty()
&& dp[i][x] - sum[i][j] <=
dp[q[j][x].back()][x] - sum[q[j][x].back()][j])
q[j][x].pop_back();
q[j][x].push_back(i);
}
}
int ans = INF;
for(int i = 1; i <= n; i++)
ans = min(ans, dp[m][i]);
printf("%d\n", ans - cost);
}
return 0;
}
vijos 1243 生产产品 DP + 单调队列优化的更多相关文章
- Vijos 1243 生产产品 (单调队列优化的动态规划)
题意:中文题.不说了. 注意一些地方,机器的执行过程是没有顺序的,而且每个机器可以用多次.第一次执行的机器不消耗转移时间K. 用dp[i][j]表示第i个机器完成第j个步骤的最短时间,sum[j][i ...
- Vijos P1243 生产产品 (单调队列优化DP)
题意: 必须严格按顺序执行M个步骤来生产一个产品,每一个步骤都可以在N台机器中的任何一台完成.机器i完成第j个步骤的时间为T[i][j].把半成品从一台机器上搬到另一台机器上也需要一定的时间K.每台机 ...
- vijos P1243 生产产品(单调队列+DP)
P1243生产产品 描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...
- 2018.10.23 vijo1243生产产品(单调队列优化dp)
传送门 这道单调队列真的有点难写啊. 方程感觉挺简单的. f[i][j]f[i][j]f[i][j]表示在第iii个车间结束前jjj次步骤的最小代价. 然后用单调队列毒瘤优化一下就行了. 代码: #i ...
- [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的数也都会被删除,你可 ...
随机推荐
- 学习调用第三方的WebService服务
互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的应用中显示,下面就以查询国内手机号码归属地为例进行说明. 首先安利一 ...
- iOS- 全方位解析.crash文件崩溃报告
1.前言 想来每个iOS攻城狮,都免不了要接触.crash文件 那么什么是.crash文件? iOS app的所有崩溃记录都会记录在设备上,所以对于和我一样没有集成让用户发送崩溃报告功能的iOS开发者 ...
- CoordinatdBolt原理分析
参考链接:http://xumingming.sinaapp.com/811/twitter-storm-code-analysis-coordinated-bolt/ CoordinatedBolt ...
- Windows下多线程编程(一)
前言 熟练掌握Windows下的多线程编程,能够让我们编写出更规范多线程代码,避免不要的异常.Windows下的多线程编程非常复杂,但是了解一些常用的特性,已经能够满足我们普通多线程对性能及其他要求. ...
- Oracle忘记密码如何重置
昨天安装Oracle11g R2的时候给scott用户设置密码,当时没有显示而且还只以输入一次,可能密码输入错误,结果今天用scott用户登录果然密码不对,还好sys和system用户都正常,就进去给 ...
- Ajax修改全局变量问题解决方法(Zepto版)
前两天项目遇到一个用ajax修改全局变量的案例,一开始无法给这个全局变量修改赋值,在网上查了一下,解决如下: 修改前: var word=1; $.ajax({ url:"myJSON.js ...
- 【转】史上最浅显易懂的Git教程!
之前一直在找git的学习教程,网上搜到很多,但是大多数写的都非常简单或者混乱,你知道技术男的思维就是以为他抛一个专业术语出来,以为你都懂……或者简单写两句,插个图,他觉得他懂了,你也能懂,事实上初学者 ...
- LeetCode 696. Count Binary Substrings
Give a string s, count the number of non-empty (contiguous) substrings that have the same number of ...
- 51nod 1292 字符串中的最大值V2(后缀自动机)
题意: 有一个字符串T.字符串S的F函数值可以如下计算:F(S) = L * S在T中出现的次数(L为字符串S的长度).求所有T的子串S中,函数F(S)的最大值. 题解: 求T的后缀自动机,然后所有每 ...
- C++四种类型转化
2018-08-02 (星期四)C++类型转换:static_cast提供编译时期静态类型检测: static_cast <type-id> (expression) 1)完成 ...