墓地雕塑-LA3708

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=20&page=show_problem&problem=1709php

在一個周長爲10000的圓上等距分佈着n個雕塑。如今又有m個新雕塑加入(位置能夠隨意放),但願全部n+m個雕塑在圓周上均勻分佈。這就須要移動其中一些原有的雕塑。要求n個雕塑移動的總距離儘可能小。算法

2<=n<=1000, 1<=m<=1000,輸出最小總距離,精確到10-4函數

 

這題是《算法競賽入門經典--訓練指南》第七頁的一道例題,做者分析的時候聲稱必定有一個雕塑沒有移動,可是沒給出證實spa

我也無法給出證實,由於裏面涉及到round(返回最接近的整數)這種非線性函數,有點難處理code

可是我想到能夠用Matlab畫個圖驗證一下是否是這樣,其實只要肯定舊的n個點中的一個點在新的n+m個點構成的環上的位置,其他的點就都肯定了,咱們隨便找一個點,讓它在一個區間上移動,算出其在各個位置處對應的總距離。我預計這個圖多是中間凹,兩邊高,實際上並不是如此,而是有不少峯。blog

在這個圖中,n=7(注意到圖中恰有7個峯),m=32,區間被分紅1000份。峯的個數彷佛是n/gcd(n,m),對n=8,m=32和n=6,m=2都成立,可是對n=8,m=18就不成立(沒有峯),我表示搞不懂,概括不出這個公式……ci

因此,從圖中可見,讓該點處於區間一端確實可使得總距離最小,可是這個點還有其餘位置能夠放,如上圖中區間中部的6個最低點。(可是做者聲稱的必定有一個雕塑沒移動,貌似也是對的)get

Matlab代碼以下:io

%uva online judge LA 3708, test, <算法競賽入門經典訓練指南>第7頁
n = 7;%original points on a circle
m = 32;% points to be added
dist = (n + m) / n;
step = 0.001;
total = zeros(1, 1 / step + 1);
t_idx = 0;
for start = 0 : step : 1
    t_idx = t_idx + 1;
    for idx = 0 : n - 1
        point = start + idx * dist;
        total(t_idx) = total(t_idx) + abs(point - round(point));
    end
end
plot(total) %此圖與m無關,只與n有關

另外還畫了一個在取定一個雕塑不動的狀況下,總距離隨m,n變化的3D圖:入門

代碼以下:

%uva online judge LA 3708, test2, <算法競賽入門經典訓練指南>第7頁
%假設圈長爲1,爲計算方便,先假設圈長爲n+m,而後再縮放一下
%n = 7;%original points on a circle
%m = 8;% points to be added

MAX = 30;%max test points for n
total = zeros(MAX, MAX);
start = 0;
for n = 1:MAX
    for m = 1 : MAX
        dist = (n + m) / n;
        for idx = 0 : n - 1
            point = start + idx * dist;
            total(n,m) = total(n,m) + abs(point - round(point));
        end
        total(n,m) = total(n,m) / (m + n);
    end
end
figure, mesh(total)
相關文章
相關標籤/搜索