1. 程式人生 > >整數劃分問題 dp 動態規劃

整數劃分問題 dp 動態規劃

原文:https://blog.csdn.net/u013377068/article/details/79765694#comments

假設我們有一個整數n,我們要對它在約束條件不同的情況下進行劃分。

1.把n劃分成不小於m(且為正整數)的劃分數

2.把n劃分成為k個正整數的劃分數

3.把n劃分成k個奇數的劃分數

1.把n劃分成不小於m(且為正整數)的劃分數

—————————————————————————————————————————————

狀態dp[i][j]代表把i劃分為不小於j的劃分數。

1.把n劃分為不小於m但可以存在相同數時的劃分數

    這種情況的劃分數的方案可以分為兩類1.不包括m

                                                              2.至少包括一個m;

    第一類:dp[n][m-1],我們可以看做把n劃分為小於m的劃分數,就能保證不包括m;

    第二類:dp[n-m][m], 我們可以看做把對n去掉m後的數,進行不小於m的劃分,就能保證至少包括一個m;

dp[i][j]=dp[i][j-1]+dp[i-j][j];

2.把n劃分為不小於m,且每個人數都不相同時的劃分數

    這種情況的劃分數的方案可以分為兩類1.不包括m

                                                              2.只有一個m

    第一類:dp[n][m-1],我們可以看做把n劃分為小於m的劃分數,就能保證不包括m;

    第二類:dp[n-m][m-1], 我們可以看做把對n去掉m後的數,進行小於m的劃分,就能保證只包括一個m;

dp[i][j]=dp[i][j-1]+dp[i-j][j-1];

—————————————————————————————————————————————

2.把n劃分為k個正整數的劃分數

—————————————————————————————————————————————

狀態dp[i][j] 為把i劃分為j個正整數的劃分數

1.把n劃分為k個可以相等的數的劃分數

    這種情況可以分為兩類1.至少一個1

                                      2.一個1也沒有(也可以看做都是>=2)

    第一類:dp[n-1][k-1],我們可以先拿出一個1分配到其中一份,接著將剩下的n-1分配到k-1份上,就能保證

                  至少一個1;

    第二類:dp[n-k][k],我們可以先拿出k個1平均分配到k份(這個保證了每個都為1),接著將剩下n-k分配到

                  k份(保證每份中至少分配到1),就能保證k份中一個1也沒有。(因為1加上一個大於等於1的數

                   一定>=2)。

dp[i][j]=dp[i-1][j-1]+dp[i-j][j];

2.把n劃分為k個不相等的數的劃分數

    這種情況可以分為兩類1.只有一個1

                                      2.一個1也沒有(也可以看做都是>=2)

    第一類:dp[n-k][k-1],我們可以先拿出k個1平均分配到k份(這個保證了每個都為1),接著將剩下n-k分配

                  到k-1份(保證除了一份有1外,其他的都>=2),就能保證k份中除了一份有1其它的都>=1(只有一

                  個1);

    第二類:dp[n-k][k],我們可以先拿出k個1平均分配到k份(這個保證了每個都為1),接著將剩下n-k分配到

                  k份(保證每份中至少分配到1),就能保證k份中一個1也沒有。(因為1加上一個大於等於1的數一

                  定>=2)。

dp[i][j]=dp[i-j][j-1]+dp[i-j][j];

—————————————————————————————————————————————

3.把n劃分為k個奇數的劃分數

—————————————————————————————————————————————

dp[i][j]為把i劃分為j個奇數的劃分數

1.把n劃分為k個可以相同的奇數的劃分數

    這種情況可以分為兩類1.至少一個1

                                      2.一個1也沒有(也可以看做>=3,因為必須是奇數)

    第一類:dp[n-1][k-1],我們可以先拿出一個1分配到其中一份,接著將剩下的n-1分配到k-1份上,就能保證

                  至少一個1;

    第二類:dp[n-2*k][k],我們可以先拿出k個2分配到其中的k份,接下來的n-2*k分配到k份中(這樣就保證了

                  每份都>=3,也就是一個1也沒有);

dp[i][j]=dp[i-1][j-1]+dp[i-2*k][k];

2.把n劃分為k個不相同的奇數的劃分數

    這種情況可以分為兩類1.只有一個1

                                      2.一個1也沒有(也可以看做>=3,因為必須是奇數)

    第一類:dp[i-2*k+1][k-1],dp[i-2*k+1][k-1]可以看做dp[i-2*(k-1)-1][k-1],我們可以拿出(k-1)個2平均分配

                  (k-1)份上,然後拿出一個1分配到不為2的那一份上。接下來將i-2*(k-1)-1分配到都為2的(k-1)份上

                  這樣就保證了這k-1份都>=3;

    第二類:dp[n-2*k][k],我們可以先拿出k個2分配到其中的k份,接下來的n-2*k分配到k份中(這樣就保證了

                  每份都>=3,也就是一個1也沒有);

dp[i][j]=dp[i-2*k+1][k-1]+dp[i-2*k][k];

—————————————————————————————————————————————