POJ 3154 Graveyard【多解,数论,贪心】
Graveyard
| Time Limit: 2000MS | Memory Limit: 65536K | |||
| Total Submissions: 1707 | Accepted: 860 | Special Judge | ||
Description
Programming contests became so popular in the year 2397 that the governor of New Earck — the largest human-inhabited planet of the galaxy — opened a special Alley of Contestant Memories (ACM) at the local graveyard. The ACM encircles a green park, and holds the holographic statues of famous contestants placed equidistantly along the park perimeter. The alley has to be renewed from time to time when a new group of memorials arrives.
When new memorials are added, the exact place for each can be selected arbitrarily along the ACM, but the equidistant disposition must be maintained by moving some of the old statues along the alley.
Surprisingly, humans are still quite superstitious in 24th century: the graveyard keepers believe the holograms are holding dead people souls, and thus always try to renew the ACM with minimal possible movements of existing statues (besides, the holographic equipment is very heavy). Statues are moved along the park perimeter. Your work is to find a renewal plan which minimizes the sum of travel distances of all statues. Installation of a new hologram adds no distance penalty, so choose the places for newcomers wisely!
Input
Input file contains two integer numbers: n — the number of holographic statues initially located at the ACM, and m — the number of statues to be added (2 ≤ n ≤ 1000, 1 ≤ m ≤ 1000). The length of the alley along the park perimeter is exactly 10 000 feet.
Output
Write a single real number to the output file — the minimal sum of travel distances of all statues (in feet). The answer must be precise to at least 4 digits after decimal point.
Sample Input
sample input #1
2 1 sample input #2
2 3 sample input #3
3 1 sample input #4
10 10
Sample Output
sample output #1
1666.6667 sample output #2
1000.0 sample output #3
1666.6667 sample output #4
0.0
Hint

Pictures show the first three examples. Marked circles denote original statues, empty circles denote new equidistant places, arrows denote movement plans for existing statues.
Source
题意:一个圆上原先均匀分布着n个点(可移动),现要加入新的m个点,使(n+m)个点仍然均匀分布在圆上,m个点可任意加在任意位置,求重新均匀分布时,原来n个点的移动距离的和的最小值。
这是lrj大白书上的一道题目(P7)。
数论解法:
证明思路,证明这个算法需要证明两个结论:
结论一:无论新的方案和旧的方案的相对位置是什么样的,对于原先的n个点来说,最好的策略就是往最近的新点位置上走。
这个结论唯一一个需要想一下的地方是,两个旧点会不会站到一个坑里去。可以证明这是不会的,设旧的方案两个点之间距离为L,新的方案两个点之间距离为X,若两个旧点A,B跑到了同一个新点O上,就说明,|AO| < x/2 && |AB| < x/2 ,则L = |AB| <= |AO| + |BO| < 2*(X/2) = X ,但事实上,L > X。反正就是不会碰在一起。
结论二:在结论一的前提下,有至少一个点重合的方案是最佳方案。
首先,一开始是n个点,后来是n+m个点,就是说一开始间隔是1/n,后来是1/(n+m)。为了但是用分数看实在不方便,我们取1/(n*(n+m))为基本单位,这样,旧的间隔是n+m,后来的间隔是n。在这里请假设n与n+m互质,如果不是互质,我们就进行约分,原因后来会知道。
然后,我们先假设有新的方案和旧的方案有一个点是重合的,其中红色的线段和点是旧的方案,蓝色的是新的方案;
然后我们沿着这个重合的点,将圆环剪开,注意首尾相同,颜色没有变哦。
你有看出什么东西吗?好吧,如果没有,那么请你看下一步,将AB‘,B’D , DC',C'A线段(即所有的蓝色点间隔形成的线段)重合。
好吧,让我们从代数的角度重新审视一下上面这个东西。设k = n+m,已经保证了k和n是互质的。看下面这段代码。
for(int i=;i<n;i++)
a[i] = i*k%n;
sort(a,a+n);
在这之后,如果你输入数组a的值,你会得到0,1,2,3....n-1,这样的序列。这是由两个数互质的性质决定的,具体证明可以采用反证法。
然后说了那么多,这个和我们的结论有什么关系呢?
既然所有的节点都到了一段区间,我们就不用管它到底是一个圆还是一条线段,从上面那个图上可以直接看出,B应该往左靠,C应该往右靠。
如果在这种情况下,我们选择转动A点,没转动x,A到最近点的距离增大x,B到最近点的距离增大x,C到最近点的距离减少x,B,C的影响抵消,所以总距离增大,这个增大的趋势一直到A,B,C三个点移动到了四等分该线段的时候,
,
然后A的最短距离增大,B,C的最短距离减少,总体距离减少。但是最终再次形成重合的时候,又是一样的。所以先增后尖,最小值在两端。
综合结论1,2该问题圆满解决。也因此获得了上面那个算法,一开始就将所有的关系投影到一个线段上。那个累加ans过程就来自以上分析。
值得一提的是,如果不进行约分的话,在很多情况下,答案也是对的,得益于映射到线段时良好的对称性。但是n和m存在倍数关系就不行了。
#include <stdio.h>
#define min(a,b) (a)>(b)?(b):(a)
int gcd(int a,int b)
{
return b==?a:gcd(b,a%b);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int temp=gcd(n,m);
n/=temp;
m/=temp;
int ans=;
for(int i=;i<n;i++)
ans+=min(i,n-i);
printf("%.4lf\n",(double)ans/(n*(n+m))*);
}
return ;
}
lrj解法(直接贪心,然后求最小距离(按比例缩小)):
#include <stdio.h>
#include <math.h>
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
double ans=0.0;
for(int i=;i<n;i++)
{
double pos=(double)i/n*(n+m);
ans+=fabs(pos-floor(pos+0.5))/(n+m);
}
printf("%.4lf\n",ans*);
}
return ;
}
POJ 3154 Graveyard【多解,数论,贪心】的更多相关文章
- poj 3154 Graveyard 贪心
//poj 3154 //sep9 #include <iostream> #include <cmath> using namespace std; double a[204 ...
- LA 3708 && POJ 3154 Graveyard (思维)
题意:在周长为10000的圆上等距分布着n个雕塑,现在又加入m个,现在让m+n个等距分布,那就得移动一些原有的雕塑,问你移动的最少总距离是多少. 析:首先我们可以知道,至少有一个雕塑是可以不用移动的, ...
- Tsinsen A1504. Book(王迪) 数论,贪心
题目:http://www.tsinsen.com/A1504 A1504. Book(王迪) 时间限制:1.0s 内存限制:256.0MB Special Judge 总提交次数:359 ...
- ACM: POJ 1061 青蛙的约会 -数论专题-扩展欧几里德
POJ 1061 青蛙的约会 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%lld & %llu Descr ...
- [POJ 2586] Y2K Accounting Bug (贪心)
题目链接:http://poj.org/problem?id=2586 题目大意:(真难读懂啊)给你两个数,s,d,意思是MS公司每个月可能赚钱,也可能赔钱,如果赚钱的话,就是赚s元,如果赔钱的话,就 ...
- poj 2010 Moo University - Financial Aid (贪心+线段树)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 骗一下访问量.... 题意大概是:从c个中选出n个 ...
- poj 1328 Radar Installation (简单的贪心)
Radar Installation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42925 Accepted: 94 ...
- POJ 2370 Democracy in danger(简单贪心)
Democracy in danger Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3388 Accepted: 25 ...
- 【POJ】1862:Stripies【贪心】【优先队列】
Stripies Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 20456 Accepted: 9098 Descrip ...
随机推荐
- Java中数据类型及其之间的转换(转)
Java中数据类型及其之间的转换 基本的数据类型 基本类型有以下四种:1)int长度数据类型有:byte(8bits).short(16bits).int(32bits).long(64bits).2 ...
- 解决vue.js修改数据无法触发视图
data:{checkValue:{}}that.checkValue[key] = [] 赋值无法实时改变变量:(数据其实最终被修改,但是并没有触发检测从而更新视图)原因:Vue 不能检测到对象属性 ...
- IOS学习3——代理
本文转载自:你真的了解iOS代理设计模式吗? 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存 ...
- iOS OC利用imageview属性切出类似圆柱图形
效果一: 效果二: 上边的图形我也数不出来名字,,暂称圆柱正切图形吧,看到这样的需求似不似在想各种插件,各种切图方法了呢... UIImageView的属性可以轻松搞定 UIViewContentMo ...
- LAMP第一部分-环境搭建
1. 安装mysqlcd /usr/local/src/ wget http://syslab.comsenz.com/downloads/linux/mysql-5.1.40-linux-i686- ...
- linux下后台运行MATLAB
原帖:http://sypeterli1.blog.163.com/blog/static/2283740492013101745824207/ 后台运行matlab脚本文件的方法:nohup ...
- MySQL如何找到表与表之间的关系?
如何找到两张表之间的关系? 先站在左表的角度上去找,如果可以找到左表的多个字段可以对应右表的一个字段,那么左表的一个字段foregin key右表的一个字段.一般情况下为id... 2.如果右表的多个 ...
- thinkinginjava学习笔记09_内部类
定义与创建 将一个类定义放在另一个类.方法.作用域.匿名类等地方,就是内部类:内部类只能由外部类对象创建(通过外部方法或者.new方法),内部类对象创建时必须已经有一个外部类对象,并且与之连接(在内部 ...
- Python学习_09_模块
模块 模块是python中的最高组织单元,在物理层面上,模块以文件存储,模块的文件名就是模块的名字.py,每个模块都有自己的名称空间. python按照路径搜索来查找模块文件,在PYTHONPATH环 ...
- MySQL安装的三种方式
.markdown-preview:not([data-use-github-style]) { padding: 2em; font-size: 1.2em; color: rgb(171, 178 ...