洛谷 P1510 精衛填海(滾動陣列 記憶化DP)

2021-09-29 09:33:15 字數 1292 閱讀 3422

題目大意:

我們可以購買n件物品,每件物品都有重量w和價值v,現在問:

已知揹包容量為c,那麼我們能不能購買物品到達價值v呢,若可以達到我們最少需要多少重量就可以到達呢?

解題思路:

典型的01揹包問題。轉移方程為:

i是代表我們購買到第i個。c代表我們剩餘的容量。m代表本個物品的重量,k代表本個物品的價值。dp[i][c]代表購買到第i個剩餘容量為c我們最大可以到達多少價值。

最後通過dp把表填完。

在不考慮mle情況下,可以快速寫出記憶化dp:

#include using namespace std;

int v,n,c;

vectorcub;

vectorhp;

vector> memo;

const int inf=-1e9;

int dfs(int u,int wei)

int main()

memo.resize(n,vector(c,-1));

dfs(0,c);

if(memo[0][c]=v)

}

每個問題都可以用子問題解決。

大佬們都是使用刷表法。刷表法每次都相當於在做決策。

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

}/*0/1揹包*/

一開始沒搞懂為什麼刷表法是合理的。其實刷表法每次也相當於在做決策。意思是我當前的重量是可以右之前的重量轉移過來。比如這裡第一次轉移時候 相當於保證這個狀態最少為m[i]。

#include using namespace std;

int v, n, c;

vectorcub;

vectorhp;

const int maxn = 1e4 + 10;

int dp[2][maxn];

const int inf = 1e9;

int main()

memset(dp, 0, sizeof(dp));

int cur = 0;

for(int h=hp[0];h<=c;h++)

dp[cur][h] = cub[0];

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

} if (dp[cur][c] < v)cout << "impossible" << endl;

else for (int cc = 0; cc <= c; cc++)

} return 0;

}

洛谷 P1510 精衛填海

一看就是典型的揹包題。裸的揹包題。然而唯一的坑點就是體積大於剩下的坑也可以補上。按理來講應該塞不下去呀 但是寫 確實只過了第乙個點。includeusing namespace std int v,n,c,ans 1 int volume 10001 energy 10001 體積 體力 int f...

洛谷P1510 精衛填海

版權說明 本題為改編題。問題描述 發鳩之山,其上多柘木。有鳥焉,其狀如烏,文首,白喙,赤足,名曰精衛,其名自詨。是炎帝之少女,名曰女娃。女娃遊於東海,溺而不返,故為精衛。常銜西山之木石,以堙於東海。山海經 精衛終於快把東海填平了!只剩下了最後的一小片區域了。同時,西山上的木石也已經不多了。精衛能把東...

洛谷 P1510 精衛填海

題目 精衛填海 題目描述 版權說明 本題為改編題。問題描述 發鳩之山,其上多柘木。有鳥焉,其狀如烏,文首,白喙,赤足,名曰精衛,其名自詨。是炎帝之少女,名曰女娃。女娃遊於東海,溺而不返,故為精衛。常銜西山之木石,以堙於東海。山海經 精衛終於快把東海填平了!只剩下了最後的一小片區域了。同時,西山上的木...