多重部分和問題 DP

2021-07-01 18:44:29 字數 775 閱讀 1039

這題是挑戰程式設計競賽上的。

題意:n個不同的數字,每個有xi個,要恰好組成k這個數是否可能.

如果單純用dp[i][j]表示前i種數,和為j是否可能,那麼轉移方程就是:

dp[i][j]=dp[i][j]||dp[i-1][j-k*a[i]]  k=min(j/a[i],x[i])

複雜度為o(n^3)

如果利用多重揹包二進位制的思想把數字按照個數分成其他數字,則可以將複雜度降為o(n^2lg(n))

但是這個題是可以做到o(n^2)的。

具體方法是定義狀態dp[i][j]表示前i種數,和恰好為j時剩餘最多a[i]的數量。也就是說前面我們在推dp[i][j]時,只用到了dp[i-1][k]的值,但是其實在計算q

狀態轉移

dp[i][j]=x[i];(dp[i-1][j]>0)

dp[i][j]=dp[i][j-a[i]]-1;(dp[i][j-a[i]]>0)

dp[i][j]=-1;(dp[i][j-a[i]]<=0)

看到轉移方程於是可以變為一維。

**。

#include #include #include using namespace std;

const int maxn = 105;

const int maxk = 100005;

int dp[maxn][maxk]; //dp[i][j]表示前i個數 恰好和為j時 第i個數最多剩多少.

int f[maxk];

int main()

多重部分和問題

有 n 種物品,第i種物品的每個物品的價值是 ai 數目是 mi 判斷是否可以選擇若干數字使得價值和是k。1 n 100 1 ai,m i,10 5 1 k 105 看作揹包大小是k,物品的價值和體積都是ai 物品數目是 mi 的多重揹包。如果最大價值是 k 的話就是可以選出,否則便是不能選出。利用...

多重部分和問題

有n種不同大小的數字a i 每種各m i 個。判斷是否可以從這些數字之中選出若干使它們的和恰好為k。dp i 表示以a i 為末尾的最長上公升子串行的長度。include include include includeusing namespace std define maxn 10010 int...

多重部分和問題

有n種不同大小的數字a i 每種各m i 個。判斷是否可以從這些數字中選出若干使它們的和恰好為k。限制條件 1 n 100,1 a i m i 100000,1 k 100000 這個問題可以用dp求解,如何定義遞推式影響最後的時間複雜度。定義dp i 1 j 用前i 1種數字 數字的編號是從0到i...