整數劃分問題 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];
—————————————————————————————————————————————