3月31:蘑菇街实习笔试:求桌子达最大平衡的代价
Posted RenewDo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3月31:蘑菇街实习笔试:求桌子达最大平衡的代价相关的知识,希望对你有一定的参考价值。
题目:
桌子有N 条腿,当桌子不平衡时可以通过砍掉某些来达到最大平衡状态。所谓最大平衡状态是指--桌子最长腿的条数超过桌子的腿总数的一半以上。但桌子的各条腿砍去的代价是不同的,要求达到最大平衡状态时所花的代价最小。
输入:
6
2 2 1 1 3 3
4 3 5 5 2 1
输出:
8
下面这种是昨晚自己想法,时间太短没调出来,今天又完善了:
#include <string> #include <vector> #include <set> #include <map> #include<cctype> #include<iostream> #include<string> using namespace std; int main() { int n; while(cin>>n) { vector<int> l(n,0); vector<int> d(n,0); int i=0; while(i++<n) cin>>l[i-1]; i=0; while(i++<n) cin>>d[i-1]; i=0; if(n==1) { cout<<0<<endl; continue; } map<int,multiset<int>> res; for(int i=0;i<l.size();i++) { if(res.find(l[i])==res.end()) { multiset<int>tmp; tmp.insert(d[i]); pair<int,multiset<int>>temp(l[i],tmp); res.insert(temp); } else { res[l[i]].insert(d[i]); } } multiset<int>cost; map<int,multiset<int>>::iterator res_i=res.begin(); map<int,multiset<int>>::iterator res_j; map<int,multiset<int>>::iterator res_k; for(;res_i!=res.end();res_i++) { int sum=0; //每次代价总数 int count=n-(*res_i).second.size(); //每次的应该桌腿总数 ++res_i; for( res_j=res_i;res_j!=res.end();res_j++)//后面长的腿 { count-=(*res_j).second.size(); for(multiset<int>::iterator m=(*res_j).second.begin();m!=(*res_j).second.end();m++) { sum+=*m; } } res_i--; if((*res_i).second.size()>count) { cost.insert(sum); continue; } else{ multiset<int> before_d; for(res_k=res.begin();res_k!=res_i;res_k++) { for(multiset<int>::iterator m=(*res_k).second.begin();m!=(*res_k).second.end();m++) { before_d.insert(*m); } } multiset<int>::iterator it=before_d.begin(); for(count;count>(*res_i).second.size()-1;count--,it++) { sum+=*it; } cost.insert(sum); } } cout<<*(cost.begin())<<endl; } return 0; }
上面是利用map实现两个元素排列的。
下面这种是利用定义类进行封装,还要进行重载函数:
#include <string> #include <vector> #include <set> #include <map> #include<cctype> #include<iostream> #include<string> #include<algorithm> using namespace std; class Leg { public: int length; int cost; Leg(int x,int y):length(x),cost(y){} bool operator < (const Leg& a) const //不加const会报错的 { return length<a.length; } bool operator=(const Leg& a)const { return length==a.length; } }; class Leg_cost { public: int length; int cost; Leg_cost(int x,int y):length(x),cost(y){} bool operator <(const Leg_cost& a) const { return cost<a.cost; } }; int main() { int n; while(cin>>n) { multiset<Leg> res; set<int>len; vector<int>l(n,0); int i=0; while(i++ < n) { cin>>l[i-1]; len.insert(l[i-1]); } i=0; while(i++ < n) { int tmp; cin>>tmp; res.insert(Leg(l[i-1],tmp)); } pair<multiset<Leg>::iterator ,multiset<Leg>::iterator>max; multiset<int>min_cost; for(set<int>::iterator cur=len.begin();cur!=len.end();cur++) { int count=n-res.count(Leg(*cur,0)); int sum=0; max=res.equal_range(Leg(*cur,0)); //[)之前定义<时,还比较了cost,后来发现equal_range的内部实现函数用的是<,所以取消了cost比较 for(multiset<Leg>::iterator after=max.second;after!=res.end();after++) { sum+=after->cost; count--; } if(res.count(Leg(*cur,0))>count) { min_cost.insert(sum); continue; } else { multiset<Leg_cost>del_cost; multiset<Leg_cost>::iterator it; for(multiset<Leg>::iterator before=res.begin();before!=max.first;before++) { del_cost.insert(Leg_cost(before->length,before->cost)); } for(it=del_cost.begin();count>res.count(Leg(*cur,0))-1;count--) { sum+=it->cost; } min_cost.insert(sum); } } cout<<*(min_cost.begin())<<endl; } return 0; }
以上是关于3月31:蘑菇街实习笔试:求桌子达最大平衡的代价的主要内容,如果未能解决你的问题,请参考以下文章