動態規劃專題

2022-09-17 15:51:15 字數 3516 閱讀 1635

在 acm 能夠開展之前,必須準備預算,並獲得必要的財力支援。該活動的主要收入來自於 irreversibly bound money (ibm)。思路很簡單。任何時候,某位 acm 會員有少量的錢時,他將所有的硬幣投入到小豬儲錢罐中。這個過程不可逆,因為只有把小豬儲錢罐打碎才能取出硬幣。在足夠長的時間之後,小豬儲錢罐中有了足夠的現金,用於支付 acm 活動所需的花費。

但是,小豬儲錢罐存在乙個大的問題,即無法確定其中有多少錢。因此,我們可能在打碎小豬儲錢罐之後,發現裡面的錢不夠。顯然,我們希望避免這種不愉快的情況。唯一的可能是,稱一下小豬儲錢罐的重量,並嘗試猜測裡面的有多少硬幣。假定我們能夠精確判斷小豬儲錢罐的重量,並且我們也知道給定幣種的所有硬幣的重量。那麼,我們可以保證小豬儲錢罐中最少有多少錢。

你的任務是找出最差的情形,即判斷小豬儲錢罐中的硬幣最少有多少錢。我們需要你的幫助。不能再貿然打碎小豬儲錢罐了!

輸入輸入包含 t 組測試資料。輸入檔案的第一行,給出了 t 的值。

對於每組測試資料,第一行包含 e 和 f 兩個整數,它們表示空的小豬儲錢罐的重量,以及裝有硬幣的小豬儲錢罐的重量。兩個重量的計量單位都是 g (克)。小豬儲錢罐的重量不會超過 10 kg (千克),即 1 <= e <= f <= 10000 。每組測試資料的第二行,有乙個整數 n (1 <= n <= 500),提供了給定幣種的不同硬幣有多少種。接下來的 n 行,每行指定一種硬幣型別,每行包含兩個整數 p 和 w (1 <= p <= 50000,1 <= w <=10000)。p 是硬幣的金額 (貨幣計量單位);w 是它的重量,以 g (克) 為計量單位。

1 #include2 #include3 #include4

using

namespace

std;

5int dp[10010

];

6int w[10010],v[10010];//

w 為重量,v為價值;

7int

main()

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

2023 dp[0]=0;24

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

28if(dp[n]==1e9) cout<

this is impossible.

"<

29else

30 33}

34return0;

35 }

view code

數字dp模板題

求2個數的區間中沒有4和62的數字的個數

1 #include2 #include3 #include4

using

namespace

std;

5 typedef long

long

ll;6

int a[20];//

分離各個數字上的數字;

7int dp[20][2];//

儲存狀態的

8int dfs(int pos,int pre,int sta,bool

limit)914

if(!limit&&dp[pos][sta]!=-1)15

18int up=limit?a[pos]:9;19

int tmp=0;20

for(int i=0;i<=up;i++)

2126

if(i==4)27

30 tmp+=dfs(pos-1,i,i==6,limit&&i==a[pos]);31}

32if(!limit)

3336

return

tmp;37}

38int solve(int

x)39

46return dfs(pos-1,-1,0,true

);47}48

intmain()

4957 memset(dp,-1,sizeof

(dp));

58 cout<1)<

60return0;

61 }

還有基本模板

1 typedef long

long

ll;

2int a[20

];

3 ll dp[20][state];//

不同題目狀態不同

4 ll dfs(int pos,/*

state變數

*/,bool lead/*

前導零*/,bool limit/*

數字上界變數

*/)//

不是每個題都要判斷前導零 5

25//

計算完,記錄狀態

26if(!limit && !lead) dp[pos][state]=ans;

27/*

這裡對應上面的記憶化,在一定條件下時記錄,保證一致性,當然如果約束條件不需要考慮lead,這裡就是lead就完全不用考慮了

*/28

return

ans;

29}

30ll solve(ll x)

31

38return dfs(pos-1

/*從最高位開始列舉

*/,/*

一系列狀態

*/,true,true);//

剛開始最高位都是有限制並且有前導零的,顯然比最高位還要高的一位視為0嘛

39}

40int

main()

41

48 }

最長上公升字序列:(hdu1257)

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

怎麼辦呢?多搞幾套系統唄!你說說倒蠻容易,成本呢?成本是個大問題啊.所以俺就到這裡來求救了,請幫助計算一下最少需要多少套攔截系統.

input

輸入若干組資料.每組資料報括:飛彈總個數(正整數),飛彈依此飛來的高度(雷達給出的高度資料是不大於30000的正整數,用空格分隔)

output

對應每組資料輸出攔截所有飛彈最少要配備多少套這種飛彈攔截系統.

sample input

8 389  207 155 300 299 170 158 65

sample output

2

#include#include

using

namespace

std;

int a[100002

];int dp[100002

];int

n;int

main()

for(int i=1;i)

}ans=max(ans,dp[i]);//

取最長的序列。

} cout

}return0;

}

view code

動態規劃專題

多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解,創立了解決這類過程優化問題的新方法 動態規劃 個人的理解 就是處於當前決策時要依賴前面的已知情況,將看似 連續無統一標準解決方案 的問題分割成多個 可以商量的 的決策過程。商量就是依靠已知的情況覺得未知 那麼什麼問題才可以用到動態規劃...

動態規劃專題

這個題,初學之時,老師教我們用分治演算法,分三路 在左邊子陣列 在右邊子陣列以及跨越中線,其實用動態規劃已經很簡單了,看狀態轉移方程就明白了 dp i beginarr i quad i 0 max quad otherwise end def maximum subarr arr if not a...

動態規劃專題

例一 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?1 include 2 include 3 include 4 include5 using namespace std 6int solution int n 遞迴做法713 int dp 11 14in...