题意:

  必须严格按顺序执行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. xml约束(转)

    在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束. 常用的约束技术XML DTD :XML Schema. XML Schema 也是一种用于定义和描述 XML 文档 ...

  2. 【技巧】断点调试你的express项目

    目录(?)[-] 写在前面 node-inspector 全局安装node-inspector 以debug模式开启express服务 启动node-inspector 调试NodeJS程序   写在 ...

  3. 教程:动手用自己电脑搭建一个网站 (nat123 花生壳 动态域名 个人电脑做服务器)

    先ps一下..今晚试了N种方法,终于找到一个靠谱 免费 好用的方法,来改装自己电脑成为服务器,在外网也能通过域名访问了!!! 需要准备的东西: Tomcat:这个是web容器,其实有了这个就已经让电脑 ...

  4. Hashtable源码剖析

    Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. Hashtabl ...

  5. ARP欺骗(完全版)

    在讲ARP欺骗之前先讲讲什么是ARP以及ARP欺骗的原理吧. 一.  什么是ARP? arp英文全称: address resolution  protocol   中文:地址解析协议 它的作用:是根 ...

  6. socket函数的使用方法(参数详解)

    socket函数的使用方法如下: int socket(int domain, int type, int protocol); 在参数表中,domain指定使用何种的地址类型,比较常用的有: PF_ ...

  7. Oracle数据库恢复之resetlogs

    实验环境:RHEL 5.4 + Oracle 11.2.0.3 如果是一名合格的Oracle DBA,对resetlogs这种关键字都应该是极其敏感的,当确认需要这种操作时一定要三思而后行,如果自己不 ...

  8. Automake使用说明

    说明 从零开始编写automake工程非常复杂也没有必要,我们只要能看懂开源项目的automake即可,然后根据自己实际情况进行修改即可,下面给出两个比较好的参考项目,其中spice-gtk涵盖了使用 ...

  9. hiho week 136(二分+优先队列)

    题目链接:http://hihocoder.com/contest/hiho136/problem/1 题意:中文题诶- 思路:直接对缓存区长度二分就好了,注意计算当前长度的"延迟惩罚值&q ...

  10. IT兄弟连 JavaWeb教程 文件下载技术

    ●  列出提供下载的文件资源 我们要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFile ...