給定n個不同大小的數字a
ia_i
ai,每種數字個m
im_i
mi個,判斷是否可以從這些數字中選出若干數是的它們的和恰好為k。
樣例輸入
3
3 5 8
3 2 2
17
這個樣例輸入的意思是一共有三種數字,分別是3、5、8,每個數字的個數分別是3、2、2.
即從3個3、2個5、2個8中是否能找出乙個組合,其和為17?
樣例輸出
yes
3個3和1個8的和就是17,所以輸出yes;反之輸出no。
典型的動態規劃就能夠求解。
d p[
i][j
]dp[i][j]
dp[i][
j]表示前i個數字(0~i
−1
0~i-1
0~i−
1號)是否能選出若干和為k。
初始化為dp[
0][0
]=
1dp[0][0]=1
dp[0][
0]=1
,d p[
0][非
零]=0
dp[0][非零]=0
dp[0][
非零]=
0,1代表yes,0代表no。從前0個數中(也就是沒有數)能選出和為0的數,但不能選出和為非零的數。
d p[
i+1]
[j
]dp[i+1][j]
dp[i+1
][j]
就是所有dp[
i][j
−k∗a
[i]]
dp[i][j-k*a[i]]
dp[i][
j−k∗
a[i]
]的值進行或運算(如果有乙個為1就為1)。
遞推式直接用**表示:
for
(int i =
0;i < n;i++)}
}
#
include
#define
maxn
105#
define
maxk
100005
intmain()
for(
int i =
0;i < n;i++
)scanf
("%d"
,&k)
;// 初始化dp
for(
int j =
1;j <= k;j++
) dp[0]
[0]=
1;for(
int i =
0;i < n;i++)}
}printf
("%d\n"
, dp[n]
[k]);}
return0;
}
多重部分和問題
有 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...