int x;
long long dp[51];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= 50; i++)
dp[i] = dp[i - 1] + dp[i - 2];
cin >> x
cout << dp[x];
long long dp[51];
int F(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (dp[n] != 0) return dp[n];
return dp[n] = F(n - 1) + F(n - 2);
}
int main() {
int x;
cin >> x;
cout << F(x);
return 0;
}
將一群物品儘量塞進背包裡面,令背包裡面的物品總價值最高。背包沒有容量限制,無論物品是什麼形狀大小,都能塞進背包;但是背包有重量限制,如果物品太重,就會撐破背包。
物品 | 價值 | 體積 |
---|---|---|
A | 5 | 11 |
B | 3 | 10 |
C | 2 | 7 |
體積限制:7 |
物品 | 價值 | 體積 |
---|---|---|
A | 5 | 11 |
B | 3 | 10 |
C | 2 | 7 |
體積限制:7 |
令陣列\(dp[i][j]\)為在 選取第\(i\)項物品 時,
\(選取物品重量 \le j\) 的最大價值。
且\(v[i]\)為第\(i\)項的價值,\(w[i]\)為第\(i\)項的重量
經過思考後,可以推出以下轉移式:
\(dp[i][j]=\)
\(\left\{
\begin{array}{l}
dp[i-1][j] \text{................................................}(j < w[i])\\
max(dp[i - 1][j], dp[i-1][j-w[i]]+v[i]\text{..}(j \ge w[i])\end{array}
\right .\)
\(dp[i][j] = max(dp[i - 1][j],\text{ } dp[i - 1][j - w[i]] + v[i])\)
舉例:\(i=3, j=10, w[i]=6, v[i]=5\)。
則\(i-1=2, \text{ }j-w[i]=4\)。
\(dp[i-1][j-w[i]]+v[i] = dp[2][4]+5\)。
第一行有正整數\(n(1 < n \le 10000)\)表有n顆鴨飼料
接下來的\(n\)行,每行有\(ab\)兩個正整數,
\(a\)代表這顆鴨飼料的體積,\(b\)代表飽足感\((1 \le a \le 100 , 1 \le b \le 5000)\)
並且鴨子最多可以吃滿100體積的飼料。
請輸出最大飽足感為何。
6
10 8
25 25
65 75
25 29
25 17
15 20
112 (選取第1,3,4項)
#include <iostream>
using namespace std;
const int maxn = 10000 + 1;
const int w_max = 100;
int dp[maxn][w_max + 1], w[maxn], v[maxn], n, ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> w[i] >> v[i];
for (int i = 1; i <= n; i++) {
for (int j = 1; j < w[i]; j++)
dp[i][j] = dp[i - 1][j];
for (int j = w[i]; j <= w_max; j++)
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
cout << dp[n][w_max];
return 0;
}
根據以上程式碼,可以透過「滾動」的技巧來降低陣列大小,因只會存取到\(dp[i]和dp[i-1]\),更以前的值不需要
則可令
\(\left\{
\begin{array}{l}
dp[i]=dp[i\text{%}2]=dp[i\text{&}1]\\
dp[i-1]=dp[(i-1) \text{%}2] =dp[!(i\text{&}1)]\end{array}
\right .\)
則程式碼可變成如下:
#include <iostream>
using namespace std;
const int maxn = 10000 + 1;
const int w_max = 100;
int dp[2][w_max + 1], w[maxn], v[maxn], n, ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> w[i] >> v[i];
for (int i = 1; i <= n; i++) {
bool now = i & 1; bool prev = !now;
for (int j = 1; j < w[i]; j++)
dp[now][j] = dp[prev][j];
for (int j = w[i]; j <= w_max; j++)
dp[now][j] = max(dp[prev][j], dp[prev][j - w[i]] + v[i]);
}
cout << dp[n & 1][w_max];
return 0;
}
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing