双机调度问题,为什么贪心不行?

lood339 2012-10-11 09:08:26
题目:http://www.codeforces.com/problemset/problem/82/D


D. 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 people, at that each of them is characterized by a positive integer 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 and aj of time to be served, the time needed to work with both of them customers is equal to 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, then he goes to the cashier, and is served within ai of time. Note that the total number of phases of serving a customer will always be equal to ⌈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.


Input

The first line of the input file contains a single number n (1 ≤ n ≤ 1000), which is the number of people in the sequence. The second line contains space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 106). The people are numbered starting from the cashier to the end of the queue.


Output

Print on the first line a single number — the minimum time needed to process all n people. Then on ⌈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 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.


Sample test(s)



Input
4
1 2 3 4

Output
6
1 2
3 4

Input
5
2 4 3 1 4

Output
8
1 3
2 5
4

题目意思:给出一个队列表示每个任务需要的时间。服务员可最多同时处理两个任务a,b,处理的时间为max(a, b)
求:总的最小处理时间,和处理的顺序
我的思路:最小化s= sum(max(ai, bj))

max(a, b) = (a + b + abs(b-a))/2, 其中a+ b是不变的,就是最小化abs(b-a),也
就是使被一起执行的a,b相差最小。这个可以用sort+贪心(这个推论可能是我出错的
原因)。长度为偶数的时候,按照顺序两两配对。如果是奇数,插入一个空任务,使他
变成偶数个任务。
struct Node
{
int val;
int idx;
Node(int v, int i):val(v),idx(i)
{
}

bool operator<(const Node& n)const
{
if(val<n.val)
{
return true;
}
else if(val == n.val)
{
return idx<n.idx;
}
return false;
}
};

void solve(const vector<int> &data)
{
int sz = data.size();
vector<Node> iNode;
for(int i = 0; i<sz; ++i)
{
iNode.push_back(Node(data[i], i+1));
}
if(sz%2 == 1)
iNode.push_back(Node(0, sz+1)); //插入辅助任务
std::sort(iNode.begin(), iNode.end());
int ret = 0;
for(int i =0; i<iNode.size(); i += 2)
{
ret += iNode[i+1].val; //max(iNode[i+1].val , iNode[i].val) = iNode[i+1].val 因为已经排序
}
cout<<ret<<endl;
vector<pair<int, int>> idx;
if(sz%2 == 1)
{
for(int i = 2; i<iNode.size(); i +=2) //保证输出的时候按照原来的idx从小到达,这个题目没有讲清楚
{
int a = iNode[i].idx;
int b = iNode[i+1].idx;
if (a>b)
{
std::swap(a, b);
}
idx.push_back(make_pair<int, int>(a, b));
}
std::sort(idx.begin(), idx.end());
for (int i = 0; i<idx.size(); ++i)
{
cout<<idx[i].first<<" "<<idx[i].second<<endl;
}
cout<<iNode[1].idx<<endl;
}
else
{
for(int i = 0; i<iNode.size(); i +=2)
{
int a = iNode[i].idx;
int b = iNode[i+1].idx;
if (a>b)
{
std::swap(a, b);
}
idx.push_back(make_pair<int, int>(a, b));
}
std::sort(idx.begin(), idx.end());
for (int i = 0; i<idx.size(); ++i)
{
cout<<idx[i].first<<" "<<idx[i].second<<endl;
}
}
}

int main()
{
//freopen("data.txt", "r", stdin);
int N = 1;
scanf("%d", &N);
vector<int> data(N);[code=C/C++]

for(int i = 0; i<N; ++i)
{
scanf("%d ", &data[i]);
}
solve(data);

return 0;
}[/code]
没有通过测试数据
网站提示使用动态规划做,但是我找不到反例说明我的方法不行。
请指点一下,多谢。
...全文
253 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
scaredkngiht 2012-10-12
  • 打赏
  • 举报
回复
你的思路是正确的

但是题意没理解到
题目标题叫做Two out of Three
文中说了then some two people of the first three standing in front of the queue are sent simultaneously

也就是说排在前面的三个人 选两个
而不是所有人中选两个

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧