洛谷普及訓練 動態規劃(3)P1164 小A點菜

2021-09-27 09:26:45 字數 1429 閱讀 6749

題目背景

uim神犇拿到了uoi的ra(鐳牌)後,立刻拉著**小a到了一家……餐館,很低端的那種。

uim指著牆上的價目表(太低階了沒有選單),說:「隨便點」。

題目描述

不過uim由於買了一些輔(e)輔(ro)書,口袋裡只剩mm元(m \le 10000)(m≤10000)。

餐館雖低端,但是菜品種類不少,有nn種(n \le 100)(n≤100),第ii種賣a_ia

i​ 元(a_i \le 1000)(a

i​ ≤1000)。由於是很低端的餐館,所以每種菜只有乙份。

小a奉行「不把錢吃光不罷休」,所以他點單一定剛好吧uim身上所有錢花完。他想知道有多少種點菜方法。

由於小a肚子太餓,所以最多只能等待11秒。

輸入格式

第一行是兩個數字,表示nn和mm。

第二行起nn個正數a_ia

i​ (可以有相同的數字,每個數字均在10001000以內)。

輸出格式

乙個正整數,表示點菜方案數,保證答案的範圍在intint之內。

輸入輸出樣例

輸入 #1複製

4 41 1 2 2

輸出 #1複製

3問題分析

這題是乙個計數性的揹包問題,要求正好花m元,可以選擇n種才,有多少種選法,並且限定了每種菜只能點一種。

最後一步子問題分解

很容易定義乙個dp[i][j]的含義為可選擇前i種,恰好劃分j元,一共有dp[i][j]種點菜方法(按照集合算,而非順序)。那麼計算dp[i][j]的方法計數可以分為兩個集合,即:

集合1:一定有最後一種菜,此時花j-list[i].v有多少種點菜方法。那麼就有dp[i-1][j-list[i].v]

集合2:一定沒有最後一種菜,此時花j元有多少種買菜方法,那麼就有dp[i-1][j]

是否有重複項

思考兩種方案的計數方法之間是否互相重複,一定是不重複的,因為兩種方法的計數中,乙個是一定沒有第i種菜的,另外乙個是一定有第i種菜的;因此兩者一定是不重複的。而兩種計數方法內部也是不重複的,因此這個計算是合理的。

計算順序與初始條件的選擇

狀態方程為dp[i][j]=dp[i-1][j-list[i].v]+dp[i-1][j]

此方程可以優化為s(m)的演算法,另外此問題的初始條件dp[0][0]=1;

#include#include#include#includeusing namespace std;

struct obj ;

int main()

vector> dp(n+1, vector(m+1));

dp[0][0] = 1;

for (int i = 1; i <= n; i++)

} cout << dp[n][m];

return 0;

}

P1044 棧(洛谷) 動態規劃

洛谷傳送門 p1044 這一題是一題很經典的動態規劃。在這裡我們知道,對於已經排到佇列中的元素對剩下的元素的排列種數沒有影響,因此僅需考慮在原佇列中的元素數目i和在棧中的元素數目j。若i為0,則待排元素的排列種數僅有一種,即將棧中的元素全部彈出。若i不為0,則dp i j dp i 1 j 1 從原...

P1564 膜拜(洛谷) 動態規劃

p1564 膜拜 這一題使用遞迴求解,考慮乙個區間 i,j 若從i到j可分在乙個機房,則直接返回,否則,遍歷每乙個點k,若 i,k 可分在乙個機房,則求 k 1,j 分組的數目最小值。求解過程中,已求的區間會被儲存起來。這裡固定n include include include define siz...

洛谷 P1020 飛彈攔截(動態規劃)

某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...