解决这个分布珠子拼图的算法?

时间:2016-02-21 01:29:30

标签: algorithm dynamic-programming graph-theory knapsack-problem

假设您有一个带有 N 点的圆圈(如下所示),并且您在广告位中分配了 N 珠子。

这是一个例子: enter image description here

每个珠子可以顺时针移动 X 插槽,这需要 X ^ 2 美元。你的目标是在每个插槽中最终得到一个珠子。您为实现这项任务需要花费的最低金额是多少?

此问题的更有趣的变化:Algorithm for distributing beads puzzle (2)?

1 个答案:

答案 0 :(得分:1)

我在MATLAB中实现了这一点。它依赖于与trincot的优秀答案完全相同的逻辑。在这个也在O(n)时间内运行的实现中,第一步是找到一个空间开始,其中一个珠子应该保持不动。我还没有证明这总能达到最佳解决方案,但也许我会回过头来。

哦,这段代码也依赖于方形金字塔公式 https://en.wikipedia.org/wiki/Square_pyramidal_number

clear; 
%// inputBps (beads per space) will be our starting point.
%// inputBps=[2 0 3 0 0 0 4 0 1 0 1 0 1 2];
%// inputBps=[2 0 2 0 0 2];
%// inputBps=[1 1 1 1 1];
inputBps=[3 0 1 0 1 0 2 2 2 1 1 0 1 0];

%// This first block of code finds a good place to start.
%// We find a candidate for a bead that should not move.
okStart = 1;
stack = 0;
for i=1:length(inputBps)
    if inputBps(i)>1
        stack = stack + inputBps(i)-1;
    end
    if inputBps(i)==0 && stack<=0
        okStart = i+1;
    end
    if inputBps(i)==0 && stack>0
        stack=stack-1;
    end
end

%// This lets us start at the space we found above.
bps = [inputBps(okStart:end) inputBps(1:okStart-1)];

sum=0;
nextFree=1;
for k=1:length(bps)
    %// firstMoves are the moves that all the beads
    %// in a space have to take because they were "forced out."
    firstMoves = nextFree-k;

    %// Say firstMoves=3 and bps(k)=2. Then our our two beads
    %// moved three spaces and four spaces, like this:
    %// sum = sum + 3^2 + 4^2.  Rewriting:
    %// sum = sum + (1^2 + 2^2 + 3^2 + 4^2) - (1^2 + 2^2)
    sum = sum + squares( bps(k) + firstMoves - 1 ) - squares( firstMoves-1 );

    %// Now calculate the next space that can accept a bead.
    nextFree = nextFree+bps(k);
end

function [ y ] = squares( x )
%SQUARES Returns sqaure payramid of input
y = x*(x+1)*(2*x+1) / 6 ;
end

问题中问题的结果:

sum =

    60