CF82D Two out of Three
题目描述
Vasya has recently developed a new algorithm to optimize the reception of customer flow and he considered the following problem.
Let the queue to the cashier contain n n n people, at that each of them is characterized by a positive integer ai a_{i} ai — that is the time needed to work with this customer. What is special about this very cashier is that it can serve two customers simultaneously. However, if two customers need ai a_{i} ai and aj a_{j} aj of time to be served, the time needed to work with both of them customers is equal to max(ai,aj) max(a_{i},a_{j}) max(ai,aj) . Please note that working with customers is an uninterruptable process, and therefore, if two people simultaneously come to the cashier, it means that they begin to be served simultaneously, and will both finish simultaneously (it is possible that one of them will have to wait).
Vasya used in his algorithm an ingenious heuristic — as long as the queue has more than one person waiting, then some two people of the first three standing in front of the queue are sent simultaneously. If the queue has only one customer number i i i , then he goes to the cashier, and is served within ai a_{i} ai of time. Note that the total number of phases of serving a customer will always be equal to ⌈n/2⌉ ⌈n/2⌉ ⌈n/2⌉ .
Vasya thinks that this method will help to cope with the queues we all hate. That's why he asked you to work out a program that will determine the minimum time during which the whole queue will be served using this algorithm.
输入格式
The first line of the input file contains a single number n n n ( 1<=n<=1000 1<=n<=1000 1<=n<=1000 ), which is the number of people in the sequence. The second line contains space-separated integers a1,a2,...,an a_{1},a_{2},...,a_{n} a1,a2,...,an ( 1<=ai<=106 1<=a_{i}<=10^{6} 1<=ai<=106 ). The people are numbered starting from the cashier to the end of the queue.
输出格式
Print on the first line a single number — the minimum time needed to process all n n n people. Then on ⌈n/2⌉ ⌈n/2⌉ ⌈n/2⌉ lines print the order in which customers will be served. Each line (probably, except for the last one) must contain two numbers separated by a space — the numbers of customers who will be served at the current stage of processing. If n n n is odd, then the last line must contain a single number — the number of the last served customer in the queue. The customers are numbered starting from 1 1 1 .
题意翻译
一队顾客排在一位收银员前面。他采取这样一个策略:每次,假如队伍有至少两人,就会从前面的前三人(如果有)中选取两位一起收银,所花费的时间为这两人单独收银所需时间的最大值。如果只有两人,那么一起收银;如果只有一人,那么单独收银。请问所需的总时间最少是多少?
输入输出样例
4
1 2 3 4
6
1 2
3 4
5
2 4 3 1 4
8
1 3
2 5
4
考虑dp
发现不好搞,在不同的情况下选择不同的数会造成不同的影响
考虑状态的设计,发现对于不同的情况,不一样的其实是当前3个数和选到了第几个数
可以在状态中记录一下目前3个数,发现只用记录前面留下的即可
设f[i][j]表示选到了第i个数,前面留下的是第j个数时的最优解
然后就没什么了
转移应该是很显而易见的
code
//¼ÓÓÍ
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int f[1001][1001],n,a[1001],out[1001][1001][3];
inline ll read()
{
char c=getchar();ll a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;
return a*b;
}
inline void az(int i,int j,int x,int y,int z){out[i][j][0]=x;out[i][j][1]=y;out[i][j][2]=z;}
void prout(int x,int y)
{
if(y==0)return;
prout(x-1,out[x][y][2]);
if(out[x][y][0]<=n)
{
cout<<out[x][y][0]<<' ';
}
if(out[x][y][1]<=n)
{
cout<<out[x][y][1]<<' ';
}
cout<<endl;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
}
memset(f,0x3f,sizeof(f));
f[1][1]=max(a[2],a[3]);f[1][2]=max(a[1],a[3]);f[1][3]=max(a[1],a[2]);
az(1,1,2,3,0);
az(1,2,1,3,0);
az(1,3,1,2,0);
int m=(n&1)?n/2+1:n/2;
for(int i=2;i<=m;i++)
{
int x=i<<1,y=i<<1|1;
for(int j=1;j<x;j++)
{
if(f[i][x]>f[i-1][j]+max(a[j],a[y]))
{
f[i][x]=f[i-1][j]+max(a[j],a[y]);
az(i,x,j,y,j);
}
if(f[i][y]>f[i-1][j]+max(a[j],a[x]))
{
f[i][y]=f[i-1][j]+max(a[j],a[x]);
az(i,y,j,x,j);
}
if(f[i][j]>f[i-1][j]+max(a[x],a[y]))
{
f[i][j]=f[i-1][j]+max(a[x],a[y]);
az(i,j,x,y,j);
}
}
}
cout<<f[m][n+1]<<endl;
prout(m,n+1);
return 0;
}
随机推荐
- MODBUS-TCP转Ethernet IP 网关连接空压机 配置案例
本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例.使用设备:欧姆龙PLC,捷米特JM-EIP-TCP网关, ETH ...
- 【调制解调】AM 调幅
说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录.本篇介绍 AM 调幅信号的调制与解调,内附全套 MATLAB 代码. 目录 说明 1. AM 调制 ...
- 论文日记四:Transformer(论文解读+NLP、CV项目实战)
导读 重磅模型transformer,在2017年发布,但就今天来说产生的影响在各个领域包括NLP.CV这些都是巨大的! Paper<Attention Is All You Need>, ...
- 在DevExpress的GridView的列中,动态创建列的时候,绑定不同的编辑处理控件
在使用DevExpress的GridView的时候,我们为了方便,往往使用一些扩展函数,动态创建GridView列的编辑控件对象,然后我们可以灵活的对内容进行编辑或者使用一些弹出的对话框窗体进行处理内 ...
- iptables防火墙调试,想打印个日志就这么难
背景 怎么会讲这个话题,这个说来真的长了.但是,长话短说,也是可以的. 我前面的文章提到,线上的服务用了c3p0数据库连接池,会偶发连接泄露问题,而分析到最后,又怀疑是db侧主动关闭连接,或者是服务所 ...
- disk test use sysbench and fio
sysbench 进入到测试目录 prepare.sh sysbench --test=fileio --file-test-mode=$1 --file-num=100 --file-total-s ...
- CTF中的神兵利刃-foremost工具之文件分离
原理 Foremost可以依据文件内的文件头和文件尾对一个文件进行分离,或者识别当前的文件是什么文件.比如拓展名被删除.被附加也仍然可以对其分离. 使用 安装: 需要使用这个工具,首先我们需要安装他, ...
- 好用的css3特性-动画和3d变换
上一篇文章总结了过渡和2D变化,这一篇来总结一下动画和3D变换,动画可用的场景也很多,比如在加载的页面的时候,可以放置一个gif图,也可以自定义小动画来缓解用户等待的焦虑感,比如以下三个小圆圈转圈圈的 ...
- vscode snnipet of python
{ // Place your snippets for python here. Each snippet is defined under a snippet name and has a pre ...
- Prism报错
Rules.Default..WithoutFastExpressionCompiler()报错 说没有找到容器 1.查看Prism.Wpf源码 获取DryIoc容器规则 2.证明项目中出现了另外一个 ...