几道贪心题目 POJ1328 radar installation POJ2054 color a tree
来源:互联网 发布:关于人工智能的弊端 编辑:程序博客网 时间:2024/05/21 06:55
题目描述简单,阅读无障碍。用贪心求解。
贪心很容易迷惑人,一不小心就贪错了。我刚开始的想法。
1、对所有的岛,按x坐标从小到大排序
2、沿x轴从左向右开始,找到第一个还没有被覆盖的岛。以该岛为圆心、雷达覆盖范围d为半径画圆。判断圆与x轴的交点,若与x轴没有交点,则无解(因为该岛无论如何也覆盖不到),若有交点,则继续。
3、以右边的交点作为雷达安装点,安装雷达,覆盖所有可以覆盖的点。
4、回到第二步
5、如果所有的岛都被覆盖了,则结束,此时已经安装的雷达总数就是最后的解。
这种想法其实是错误的。这种每次都把雷达尽力往靠x轴右边安装,看似是最优的,其实不是。那只是雷达每次能按照的最右位置,而非最优位置。“过犹不及”,有时往左一点更好。
正确的做法是这样的。
1、对每个岛,以该岛为圆心、雷达覆盖范围d为半径画圆。这个圆与x轴相交,会到一段区间。于是,所有的点都被转化为x轴上对应的区间。(呃,貌似有点像活动选择问题)
2、对每个岛在x轴上对应的区间,只要在这个区间内安装雷达,该岛就可以被覆盖到。沿x轴从左向右看,区间之间的关系无非有三种。
若两个区间不相交,则需要两个雷达,每个区间安装一个
若区间有公共部分,则需要一个雷达,按照在左区间的右端点
若一个区间在另一个区间内,则需要一个雷达,按照在小区间的右端点
3、沿x轴从左向右,当处理完所有的区间时,此时的雷达总数就是最后的解
这种做法和算法导论上的活动选择问题有点像,活动选择是在一段时间内尽可能多的安排不冲突的活动。本题是根据区间之间的相互关系,尽可能的使用最少的雷达覆盖所有的岛,慢慢体会吧。
POJ2054 color a tree
贪心问题。要使着色时间最少,最直观的想法是:使着色因子最大的点尽早的被着色。光有这点意识还不够,解决这题的关键,是要发现:着色因子最大的点一定是紧跟着它的父节点之后被着色的。严格的证明这里就讨论了,不过可以简单的理解一下:着色因子最大的点应该在可以着色的时候(即父节点之后被着色后)尽快着色。
基于上述观察,可以考虑把色因子最大的点和它的父节点合并。合并后的点着色因子是多少?原来节点着色因子的平均值。这里的平均值,是指两个被合并的集合的Ci值之和除以两个集合的大小之和,譬如两个集合A,B,A的Ci和为Ca,大小为Ta,B的Ci和为Cb,大小为Tb,则合并后为(Ca+Cb)/(Ta+Tb)。(想一想为什么?)
还要几道贪心的题目,在这里也推荐一下,相对比较简单,也可以做做,似乎更适合入门。
POJ1230 Pass Murielle
POJ1017 packets
POJ2709 painter
POJ1328
#include <iostream>#include <cmath>#include <vector>#include <algorithm>using namespace std;struct Range // the range for radar installation in the x-axis so that the radar can cover the island // the range can be got from the circle which the center is an island position in the x-y coordinates { float left; float right;};bool CompareRange( const Range& first, const Range& second ) // sort ranges with the left, and arrange them from small to large { return first.left < second.left; }int GetNumByGreedy( const vector<Range>& islands ) // caculate the minimum radar number ( Assume: islands is not empty ){ int size = islands.size(); if( size == 1 )return 1; int radarNum = 1; float pre = islands[0].right; for( int i=1; i<size; i++ ) { if( islands[i].left > pre ) // if the new range have no commond with the previous range, we need to add an extra radar { pre = islands[i].right; radarNum++; } else { if( islands[i].right < pre ) // if they have commond range, we need to find out it pre = islands[i].right; } } return radarNum;}int main(){ vector<int> result; // save the minimum radar number for each input case int islandNum; int radarRange; while( cin >> islandNum >> radarRange ) { if( islandNum == 0 && radarRange == 0 ) // end of input break; vector<Range> islands; // save the range in the x-axis for the each island bool impossible = false; for( int i=0; i<islandNum; i++ ) { int x, y; // (x,y) represents the position of island in the x-y coordinates cin >> x >> y; if( y > radarRange ) // in this case, no solution for radar installation impossible = true; if( !impossible ){float tmp = sqrt( (float)(radarRange*radarRange - y*y) );Range rg; rg.left = x - tmp;rg.right = x + tmp;islands.push_back( rg );} } if( impossible ) { result.push_back( -1 ); continue; } sort( islands.begin(), islands.end(), CompareRange ); int rlt = GetNumByGreedy( islands ); result.push_back( rlt ); // save the minimum radar number for each input case } for( int i=0; i<result.size(); i++ )cout << "Case " << i+1 << ": " << result[i] << endl; return 0;}
POJ2054
#include <iostream>#include <vector>using namespace std;#define NUM1002struct Node{bool exist;//表示节点是否已经被删除int parent;double cost;vector<int> squence;//合并后的节点序列};int nodeNum;int rootIndex;int costArray[NUM];Node tree[NUM];int GetMaxCost()//找到cost最大的节点的索引{int result;double max = 0;for( int i=1; i<=nodeNum; i++ ){if( tree[i].exist && ( tree[i].cost > max ) )//节点存在,并且不是根节点{max = tree[i].cost;result = i;}}return result;}int Solve(){int index;for( int i=1; i<nodeNum; i++ )//有nodeNum个节点,则合并nodeNum-1次,最后可剩一个节点{int max = GetMaxCost();//找到cost最大的节点的索引int parent = tree[max].parent;int maxCount = (int)tree[max].squence.size();int parentCount = (int)tree[parent].squence.size();double sum = tree[parent].cost * parentCount + tree[max].cost * maxCount;tree[parent].cost = sum / ( maxCount + parentCount );//更新父节点的索引(注意:这里不能简单的相加除2)tree[parent].squence.insert( tree[parent].squence.end(), tree[max].squence.begin(), tree[max].squence.end() );tree[max].squence.clear();for( int j=1; j<=nodeNum; j++ )//修改最大cost节点的所有孩子的父节点{if( tree[j].exist && tree[j].parent == max )tree[j].parent = parent;}tree[max].exist = false;//删除子节点index = parent;}return index;}void Output( int index ){long sum = 0;for( int i=0; i< (int)(tree[index].squence.size()); i++ ){int temp = tree[index].squence.at( i );sum += costArray[temp] * ( i+1 );}tree[index].squence.clear();printf( "%d\n", sum );}int main(){while( scanf( "%d%d", &nodeNum, &rootIndex ), !( nodeNum == 0 && rootIndex == 0 ) ){memset( tree, 0, sizeof(tree) );memset( costArray, 0, sizeof(costArray) );for( int i=1; i<=nodeNum; i++ )//输入各节点的costFactor{scanf( "%d", &costArray[i] );tree[i].cost = costArray[i];tree[i].squence.push_back( i );tree[i].exist = true;}tree[rootIndex].exist = false;//设置根节点的父节点for( int j=1; j<nodeNum; j++ )//根据边的情况,填充父子关系{int parent, child;scanf( "%d%d", &parent, &child );tree[child].parent = parent;}int x = Solve();Output( x );}return 0;}
- 几道贪心题目 POJ1328 radar installation POJ2054 color a tree
- color a tree【hdu1055】【POJ2054】贪心
- POJ1328 Radar Installation 贪心
- POJ1328 Radar Installation 贪心
- 【贪心】POJ1328 Radar Installation
- poj1328 Radar Installation 贪心
- 【POJ1328】Radar Installation 贪心
- POJ1328 Radar Installation 贪心
- 贪心- poj1328 Radar Installation
- POJ1328 Radar Installation 贪心
- poj1328 Radar Installation 贪心
- poj1328 Radar Installation 贪心
- POJ1328 Radar Installation (贪心)
- POJ1328 Radar Installation(贪心)
- POJ1328 Radar Installation(贪心)
- 【贪心】[POJ1328]Radar Installation
- POJ1328-Radar Installation(贪心)
- poj2054 Color a Tree
- Spring注解@Component、@Repository、@Service、@Controller区别
- JavaScript实现走马灯效果,上 下 左 右无缝连接、循环滚动
- 2011-08-19
- ddr2时钟由pll1和pll2的最小值决定
- Opencv 命令行模式载入图片的困惑解决
- 几道贪心题目 POJ1328 radar installation POJ2054 color a tree
- java分别采用dom,sax,jdom,dom4j操作xml
- java反射简介
- linux分辨率调整
- Jquery学习笔记——事件
- 无需SSH程序,Windows下实现Git在局域网间使用(SVN可以下岗了!)
- php实现文件上传进度条
- ScriptManager.RegisterStartupScript方法
- 轻公司"的点金术"