SRM 554 - 500 TheBrickTowerMediumDivOne

来源:互联网 发布:windows隐藏任务栏图标 编辑:程序博客网 时间:2024/04/30 19:19

题目链接:

http://community.topcoder.com/stat?c=problem_statement&pm=12161


题目大意:

对一个序列做重排列,找出权值最小的一个排列,权值相同的情况下选字典序最小的。

一个排列的权值是任相邻两元素中的较大值的和。


算法:

显然一个排列的权值是有n-1个数相加而成的,每个数最少出现0次,最多出现2次。

但是一个数如果出现0次,必定是由比它大的数代替的。

所以最理想的情况是除最小数外的每个数都出现了一次。

所以最佳的排列是一个先递减再递增的序列。

因为要保证字典序最小,所以要先贪心的找出一个字典序尽量小的递减序列,然后把剩下的数排序放在后面。


代码:

#include <string>#include <cstdio>#include <iostream>#include <algorithm>#include <sstream>#include <cstdlib>#include <cstring>#include <string>#include <climits>#include <cmath>#include <queue>#include <vector>#include <stack>#include <set>#include <map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;vector<pair<int, int> > tmp;vector<int> ans;class TheBrickTowerMediumDivOne{public:    vector <int> find(vector <int> heights)    {        ans.clear();        tmp.clear();        if (heights.size() == 1)        {            ans.push_back(0);            return ans;        }        else if (heights.size() == 2)        {            ans.push_back(0);            ans.push_back(1);            return ans;        }        else if (heights.size() == 3)        {            ans.push_back(0);            ans.push_back(1);            ans.push_back(2);            if (heights[1] > heights[0] && heights[1] > heights[2])            {                swap(ans[1], ans[2]);            }            return ans;        }        int lim = INT_MAX;        for (int i = 0; i < heights.size(); i ++)        {            if (heights[i] <= lim)            {                lim = heights[i];                ans.push_back(i);            }            else            {                tmp.push_back(make_pair(heights[i], i));            }        }        sort(tmp.begin(), tmp.end());        for (int i = 0; i < tmp.size(); i ++)        {            ans.push_back(tmp[i].second);        }        return ans;    }};


0 0
原创粉丝点击