题意:

  必须严格按顺序执行M个步骤来生产一个产品,每一个步骤都可以在N台机器中的任何一台完成。机器i完成第j个步骤的时间为T[i][j]。把半成品从一台机器上搬到另一台机器上也需要一定的时间K。每台机器最多只能连续完成产品的L个步骤。也就是说,如果有一台机器连续完成了产品的L个步骤,下一个步骤就必须换一台机器来完成。问一个产品最短需要多长时间呢?(对于100%的数据,N<=5, L<=50000,M<=100000)

题意:

  被高中生虐了~

  题意要求尽量缩短时间来完成一件产品,但是由于需要按照步骤,所以多线程的方式不必考虑。dp[i][j]=min(dp[k][p])+(sum[i][j] - sum[k][j]),dp[i][j]表示完成前i个步骤,且最后一步是在第j台机器上完成。sum[k][j]表示第j台机器完成第1~k个步骤所需要的时间和,但是k与i的距离不宜超过规定的L。式子也可以这样写:dp[i][j]=min(dp[k][p] -  sum[k][j])+ sum[i][j] ,那么就单单看这项min(dp[k][p] -  sum[k][j])就行了,这不就是类似于在序列区间a[i-L]~a[i-1]之间找一个最小值的问题?那就可以用单调队列解决了。复杂度为O(n2*m),是与L无关的。

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
const int M=;
int m, n, K, L;
int t[N][M], dp[N][M];
int que[N][M], idx[N][M], top[M], rear[M]; void calmin(int i)
{
for(int j=; j<=n; j++)
{
int tar=INF;
for(int k=; k<=n; k++)
{
if(j==k) continue;
tar=min(tar, dp[i][k]);
}
tar-=t[i][j];
while( top[j]<rear[j] && que[rear[j]-][j]>=tar ) rear[j]--;
que[rear[j]][j]=tar;
idx[rear[j]][j]=i;
rear[j]++;
}
} void init()
{
memset(dp,0x3f,sizeof(dp));
memset(top,,sizeof(top));
memset(rear,,sizeof(rear));
memset(dp[],,sizeof(dp[]));
memset(que,,sizeof(que));
memset(idx,,sizeof(idx));
for(int i=; i<=n; i++) //在单个机器上运行所有任务,求区间和
for(int j=; j<=m; j++)
t[j][i]+=t[j-][i];
for(int i=; i<=n; i++)
rear[i]++;
}
int cal()
{
init();
for(int i=; i<=m; i++) //枚举步骤
{
for(int j=; j<=n; j++) //用第j台机器来完成i项
{
while( top[j]<rear[j] && idx[top[j]][j]<i-L)
top[j]++; //过期
int &d=dp[i][j];
if( top[j]==rear[j] )
{
for(int k=; k<=n; k++)
{
if(k==j)continue;
d=min(d, dp[i-][k]);
}
d+=t[i][j]-t[i-][j];
}
else d=min(d, que[top[j]][j]+t[i][j]+K );
}
calmin(i);
} int ans=INF;
for(int i=; i<=n; i++) ans=min(ans, dp[m][i]);
return ans-K; //第一步不需要换机器费用
} int main()
{
//freopen("input.txt","r",stdin);
while(~scanf("%d%d%d%d",&m, &n, &K, &L))
{
for(int i=; i<=n; i++) //机器
for(int j=; j<=m; j++) //步骤
scanf("%d",&t[j][i]);
cout<<cal()<<endl;
}
return ;
}

AC代码

Vijos P1243 生产产品 (单调队列优化DP)的更多相关文章

  1. vijos P1243 生产产品(单调队列+DP)

      P1243生产产品   描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...

  2. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  3. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  4. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  5. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  6. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  7. 【单调队列优化dp】 分组

    [单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...

  8. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  9. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  10. BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP

    题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...

随机推荐

  1. 《Java多线程编程核心技术》读后感(十三)

    类InheritableThreadLocal的使用 使用类InheritableThreadLocal可以在子线程中取得父线程继承下来的值 值继承 package Third; import jav ...

  2. (十四)hibernate逆向工程

    一.hibernate逆向工程生成实体 介绍一个模型设计工具PowerDesigner,这个是j2ee开发必要的一个工具.一般在开发中先使用PowerDesigner 创建实体关系图即概念模型.建立了 ...

  3. dpdk学习笔记2

    一 了解dpdk准备知识 1 NAT NAT技术是为了缓解IPV4地址枯竭得问题,通过使用NAT技术,一个机构如学校可以只用单一得公网IP来范文互联网,在外界看来只有一台接入公网得设备.NAT分为两种 ...

  4. wxGlade的图标,原来是来自蒙德里安的名画!

    一直用wxGlade做GUI的,今天突然发现它的图标和一副油画很像. wxGlade的图标,图标的文件名竟然就叫做mondrian.ico 蒙德里安创造了很多这种纯粹的基本要素的作品,下面是其中之一, ...

  5. 使用gdb调试c程序莫名退出定位 exit 函数

    gdb 程序名称 b exit //设置exit函数断点 run //运行程序 bt //查看程序调用堆栈,定位到exit所在行

  6. font-size: 0;解决元素间的空白间隙

    看别人的代码看到过font-size:0这个设置,不明白为何这样操作,后来研究一下才明白:这是像素级还原设计稿很有用的设置,因为元素节点有文本节点,在缩进代码时会占据宽度,这么说不好理解,演示如下: ...

  7. Java之Spring Cloud概念介绍(非原创)

    文章大纲 一.理解微服务二.Spring Cloud知识介绍三.Spring Cloud全家桶四.参考资料下载五.参考文章 一.理解微服务   我们通过软件架构演进过程来理解什么是微服务,软件架构的发 ...

  8. c#封装dll

    https://www.cnblogs.com/xingboy/p/10287425.html

  9. [UE4]如何替换角色Mesh上的Material材质

    http://www.dawnarc.com/2016/10/ue4%E5%A6%82%E4%BD%95%E6%9B%BF%E6%8D%A2%E8%A7%92%E8%89%B2mesh%E4%B8%8 ...

  10. Android Studio如何导出可供Unity使用的aar插件详解

    http://www.cnblogs.com/xtqqkss/p/6387271.html 前言 项目之前使用Eclipse导出的jar文件来做与Android交互,最近因为工作需要需使用Androi ...