簡體   English   中英

分區編號 N分為M個分區

[英]Partitioning a no. N into M partitions

我正在嘗試一個必須對一個分區進行分區的問題。 N盡可能分成M個分區。

例:

N = 1 M = 3,將1分成3部分

0 0 1
0 1 0
1 0 0

N = 3 M = 2,將3分成2部分

2 1
1 2
3 0
0 3

N = 4 M = 4,將4分成4部分

0 0 0 4
0 0 4 0
0 4 0 0
4 0 0 0
0 0 1 3
0 1 0 3
0 1 3 0


等等。

我確實編寫了回溯算法。 它會逐步生成所有可能的合成,但是會占用較大的輸入。因為許多合成只是在零件排序上有所不同。我想減少這一點。任何人都可以幫助您提供一種更有效的方法。

我的方法:

void backt(int* part,int pos,int n) //break N into M parts
{
    if(pos==M-1)
    {
        part[pos]=n;
        ppart(part);   //print part array
        return;
    }

    if(n==0)
    {
        part[pos]=0;
        backt(part,pos+1,0);
        return;
    }

    for(int i=0;i<=n;i++)
    {
        part[pos]=i;

        backt(part,pos+1,n-i);
    }
}

在我的算法中。 n為N,它為N的每個可能分區填充數組part []。

我想知道的是一旦生成一個合成,我想計算該合成將以不同順序發生多少次。例如:對於N = 1,M = 3 :::合成只有一個:<0,0,1 >,但發生3次。 那就是我想知道的每種可能的獨特構圖。

再舉一個例子:N = 4 M = 4

組成<0 0 0 4>被重復4次。 同樣,對於每種獨特的成分,我都想確切知道它將發生多少次。

看起來我也可以通過在這里解釋來理解它。

謝謝。

您可以將int轉換為分區,如下所示:

vector<int> part(int i, int n, int m)
{
    int r = n; // r is num items remaining to be allocated

    vector<int> result(m, 0); // m entries inited to 0

    for (int j = 0; j < m-1; j++)
    {
        if (r == 0) // if none left stop
            break;

        int k = i % r; // mod out next bucket
        i /= r; // divide out bucket
        result[j] = k; // assign bucket
        r -= k; // remove assigned items from remaining
    }

    result[m-1] = r; // put remainder in last bucket

    return result;
}

因此,您可以按以下方式使用它:

for (int i = 0; true; i++)
{
    vector<int> p = part(i, 3, 4);

    if (i != 0 && p.back() == 3) // last part
       break;

    ... // use p

};

由此也應該清楚如何制作零件的增量版本。

一種更簡單,更數學的方法:

此問題等效於在表達式f(x)=(1 + x + x ^ 2 + x ^ 3 + .... + x ^ N)^ M中找到x ^ N的系數

f(x)=((x ^(N-1)-1)/(x-1))^ M將其微分M倍(d ^ Nf(x)/ dx ^ N)且系數為( 1 / n!)*(d ^ Nf(x)/ dx ^ N)x = 0;

可以使用任何數值微分技術來完成微分。 因此,算法的復雜度為O(N * complexity_of_differentiation)。

給定n個數字的排列數組,計算編號。 元組 (i,j,k,l,m) 使得 i <j<k<l<m and a[i]<a[k]<a[j]<a[m]<a[l]< div><div id="text_translate"><p> 對於軟件開發人員面試的硬算法回合,我最近被問到這個問題。 我能夠使用蠻力/遞歸來做到這一點,不確定預期的方法,對此有什么幫助嗎?</p><blockquote><p> 給定n數字的排列數組,計算元組數(i,j,k,l,m)使得i&lt;j&lt;k&lt;l&lt;m和a[i]&lt;a[k]&lt;a[j]&lt;a[m]&lt;a[l] 。</p></blockquote><p> 我的方法-&gt; 使用遞歸從給定數組中嘗試 (i,j,k,l,m) 的所有元組,並僅考慮滿足條件的元組,例如 N 選擇 5,因為這具有指數時間復雜性,我想讓它成為三次方或二次方</p></div></j<k<l<m>

[英]Given an array of permutation of n numbers calculate the no. of tuples (i,j,k,l,m) such that i<j<k<l<m and a[i]<a[k]<a[j]<a[m]<a[l]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM