1 / 18

习题选讲

习题选讲. 贪心算法. 贪心算法. 1093 Air Express 1134 积木分发 1438 Shopaholic 1140 国王的 遗产 1090 Highways. 贪心算法. 1193 Up the Stairs 1004 I Conduit! 1017 Rate of Return 1059 Exocenter of a Trian 1003 Hit or Miss 1018 A Card Trick 1052 Candy Sharing Game 1041 Pushing Boxes 1211 商人的宣传

Download Presentation

习题选讲

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 习题选讲 贪心算法

  2. 贪心算法 • 1093 Air Express • 1134 积木分发 • 1438 Shopaholic • 1140 国王的遗产 • 1090 Highways

  3. 贪心算法 • 1193 Up the Stairs • 1004 I Conduit! • 1017 Rate of Return • 1059 Exocenter of a Trian • 1003 Hit or Miss • 1018 A Card Trick • 1052 Candy Sharing Game • 1041 Pushing Boxes • 1211 商人的宣传 • 1071 Floors • 1082 MANAGER

  4. 1134 积木分发 • 题目大意: • 一个人手上有s块积木,一共有n个小朋友,每个小朋友手上有a块积木,还需要b块积木才能完成。当一个小朋友的积木完成后则全部回收利用。问是否所有小朋友都能完成。 • s<=1000000,n<=10000,a,b<=10^9

  5. 1134 积木分发 • 解题思路: • 尽量先满足需求少的小朋友,以回收得到更多积木; • 因此按小朋友的需求排序,贪心求解。

  6. 1134 积木分发 • 若两个小朋友分别已有和需求为a1,b1和a2,b2,且a1<a2,则先给第一个小朋友能完成的积木数s应该满足s>=a1 && s+b1>=a2,即s >= max(a1, a2-b1);先给第二个小朋友则s应该满足s>=a2 && s+b2>=a1,即s>=max(a2,a1-b2)>=a2。因为a2>max(a1,a2-b1),所以先给第二个小朋友的要求s更多,因此应先给第一个小朋友。

  7. 1134 积木分发 • struct child • { int a,b; }; • bool operator <(const child &x,cont child &y) • { return x.a<y.a; } • bool check(child children[],int s,int n) { • sort(children, children+n); • for (int i=0;i<n;i++) { • if (s<children[i].a) • return false; • s+=children[i].b; • } • return true; • }

  8. 1438 Shopaholic • 题目大意: • 买东西每买三件东西则最便宜的一件免费。给出n个需要买的东西的价格,问最多能免费多少? • n<=20000,价格不超过20000

  9. 1438 Shopaholic • 解题思路: • 尽量使价格高的东西免费; • 按价格从高到低排序后,每三件取一件免费; • sort(price,price+n); • for (i=n-3;i>=0;i-=3) • s+=price[i];

  10. 1140 国王的遗产 • n块金块组成一棵树,总共k个人,每个人选择树里的一条边去掉,得到不超过当前金块的一半的部分,并且分割使自己得到尽量多的金块,如果相等则使金块组编号最小。输出每个人得到的金块数量。 • n<=30000,k<=100

  11. 1140 国王的遗产 • 解题思路: • 枚举每个人的时候,检查切断每一条边所得到的金块数和组编号,并得到最大金块数和最小组编号。 • 切断每条边后,得到一棵子树,可计算得到子树节点数和最小编号; • 若每次从最小编号节点开始递归,则可以轻易比较子树的组编号以及它的补图的组编号。

  12. 1140 国王的遗产 • 每个人的答案,保存以下信息:得到的金块数,答案类型(是否包含根节点),最小编号(不包含根节点时)或缺少的最小编号(包含根节点时)去掉的边。 • struct ans { • enum anstype{withroot,withoutroot}; • int x,y,count,min; • anstype type; • };

  13. 1140 国王的遗产 • bool better(const ans &a,const ans &b) { • if (a.count!=b.count) • return a.count>b.count; • else if (a.type==ans::withroot) { • if (b.type==ans::withoutroot) • return true; • else • return a.min>b.min; • } else { • if (b.type==ans::withroot) • return false; • else • return a.min<b.min; • } • }

  14. 1140 国王的遗产 • vector<int> cal(int n,int k) { • int x=1,total=n,temp; • vector<int> ret; • for (;k>1;k--) { • best.count=-1; • x=predfs(x,-1); dfs(x,-1,temp); • erase(edge[best.x],best.y); • erase(edge[best.y],best.x); • if (best.type==ans::withroot) x=best.x; • total-=best.count; • ret.push_back(best.count); • } • ret.push_back(total); • return ret; • }

  15. 1140 国王的遗产 • int predfs(int cur,int parent) { • int min=cur; • for (int i=0;i<edge[cur].size();i++) { • if (edge[cur][i]==parent) • continue; • int temp=predfs(edge[cur][i],cur); • if (temp<min) • min=temp; • } • return min; • }

  16. 1140 国王的遗产 • int dfs(int cur,int parent,int &low) { • int subtree=1,templow=0; • low=cur; • for (int i=0;i<edge[cur].size();i++) { • if (edge[cur][i]==parent) • continue; • subtree+=dfs(edge[cur][i],cur,templow); • if (templow<low) • low=templow; • } • tempans.x=cur; • tempans.y=parent; • tempans.min=low; • // 以上找到当前节点与父节点的边的信息

  17. 1140 国王的遗产 • // 以下更新答案 • if (subtree<=total-subtree) { • tempans.count=subtree; • tempans.type=ans::withoutroot; • if (better(tempans,best)) • best=tempans; • } • if (total-subtree<=subtree&&subtree!=total) { • tempans.count=total-subtree; • tempans.type=ans::withroot; • if (better(tempans,best)) • best=tempans; • } • return subtree; • }

  18. 谢谢!

More Related