日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DFS——记忆化搜索——动态规划

發布時間:2025/3/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DFS——记忆化搜索——动态规划 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以洛谷P1802 ?5倍經驗日 為例

https://www.luogu.org/problem/show?pid=1802

題目背景

現在樂斗有活動了!每打一個人可以獲得5倍經驗!absi2011卻無奈的看著那一些比他等級高的好友,想著能否把他們干掉。干掉能拿不少經驗的。

題目描述

現在absi2011拿出了x個迷你裝藥物(嗑藥打人可恥….),準備開始與那些人打了

由于迷你裝一個只能管一次,所以absi2011要謹慎的使用這些藥,悲劇的是,沒到達最少打敗該人所用的屬性藥了他打人必輸>.<所以他用2個藥去打別人,別人卻表明3個藥才能打過,那么相當于你輸了并且這兩個屬性藥浪費了。

現在有n個好友,有輸掉拿的經驗、贏了拿的經驗、要嗑幾個藥才能打過。求出最大經驗(注意,最后要乘以5)

輸入輸出格式

輸入格式:

第一行兩個數,n和x

后面n行每行三個數,分別表示輸了拿到的經驗(lose[i])、贏了拿到的經驗(win[i])、打過要至少使用的藥數量(use[i])。

輸出格式:

一個整數,最多獲得的經驗

輸入輸出樣例

輸入樣例#1:
6 8 21 52 1 21 70 5 21 48 2 14 38 3 14 36 1 14 36 2 輸出樣例#1:
1060

說明

【Hint】

五倍經驗活動的時候,absi2011總是吃體力藥水而不是這種屬性藥>.<

【數據范圍】

對于10%的數據,保證x=0

對于30%的數據,保證n<=10,x<=20

對于60%的數據,保證n<=100,x<=100, 10<=lose[i], win[i]<=100,use[i]<=5

對于100%的數據,保證n<=1000,x<=1000,0<lose[i]<=win[i]<=1000000,0<=use[i]<=1000

明顯的一個01背包

先說本題要注意的地方

1、答案要用long long

2、如果是體力為0也可以打,+lose[i]

裸的搜索版本 ,TLE

now表示當前搜索哪個對手,expe表示當前經驗值,potion表示剩下的藥水瓶數

#include<cstdio> #include<algorithm> using namespace std; int n,x; int lose[1001],win[1001],need[1001]; long long ans; void dfs(int now,long long expe,int potion) {ans=max(ans,expe);if(now>n) return;if(need[now]<=potion) dfs(now-1,expe+win[now],potion-need[now]);dfs(now-1,expe+lose[now],potion); } int main() {scanf("%d%d",&n,&x);for(int i=1;i<=n;i++)scanf("%d%d%d",&lose[i],&win[i],&need[i]);dfs(n,0,x);printf("%lld",ans*5); }

有人可能要問為什么搜索dfs過程的now是從n到1,能不能從1到n?

答案是完全可以,因為搜索的結果與搜索順序無關

下面的記憶化搜索now也可以改成從1到n

記憶化搜索版本??55ms / ?23.51MB

可以發現主要的區別就是dfs有了返回值

#include<cstdio> #include<algorithm> using namespace std; int n,x; int lose[1001],win[1001],need[1001]; long long f[1002][1001]; long long dfs(int now,int potion) {if(!now) return 0;//邊界if(f[now][potion]) return f[now][potion];//關鍵在這一句,如果這一狀態在之前已經計算過了,直接returnif(need[now]<=potion) f[now][potion]=max(f[now][potion],dfs(now-1,potion-need[now])+win[now]); f[now][potion]=max(f[now][potion],dfs(now-1,potion)+lose[now]);return f[now][potion]; } int main() {scanf("%d%d",&n,&x);for(int i=1;i<=n;i++)scanf("%d%d%d",&lose[i],&win[i],&need[i]);printf("%lld",dfs(1,x)*5); }

DP版本??30ms /??23.5MB

由此可以看到DP與記憶化搜索的不同之處:

記憶化搜索,本質還是搜索,所以它的更新是從下往上的,即由后一個狀態來更新

DP的更新是從上往下的,即由前一個狀態來更新

所以轉化成DP時,要將記憶化搜索的更新過程反過來

#include<cstdio> #include<algorithm> using namespace std; int n,x; int lose[1001],win[1001],need[1001]; long long f[1001][1001]; int main() {scanf("%d%d",&n,&x);for(int i=1;i<=n;i++)scanf("%d%d%d",&lose[i],&win[i],&need[i]);for(int i=1;i<=n;i++)for(int j=x;j>=0;j--)if(j>=need[i]) f[i][j]=max(f[i-1][j-need[i]]+win[i],f[i-1][j]+lose[i]);else f[i][j]=f[i-1][j]+lose[i];printf("%lld",f[n][x]*5); }

?

DP版本的優化,壓去第一維??19ms /??16.04MB

#include<cstdio> #include<algorithm> using namespace std; int n,x; int lose[1001],win[1001],need[1001]; long long f[1001]; int main() {scanf("%d%d",&n,&x);for(int i=1;i<=n;i++)scanf("%d%d%d",&lose[i],&win[i],&need[i]);for(int i=1;i<=n;i++)for(int j=x;j>=0;j--)if(j>=need[i]) f[j]=max(f[j-need[i]]+win[i],f[j]+lose[i]);else f[j]+=lose[i];printf("%lld",f[x]*5); }

?

?

#include<cstdio> #include<algorithm> using namespace std; int n,x; int lose[1001],win[1001],need[1001]; long long f[1002][1001]; long long dfs(int now,int potion) {if(now>n) return 0;if(need[now]<=potion) {if(f[now+1][potion-need[now]]) f[now][potion]=max(f[now][potion],f[now+1][potion-need[now]]);else f[now][potion]=max(f[now][potion],dfs(now+1,potion-need[now])+win[now]); }if(f[now+1][potion]) f[now][potion]=max(f[now][potion],f[now+1][potion]);else f[now][potion]=max(f[now][potion],dfs(now+1,potion)+lose[now]);return f[now][potion]; } int main() {scanf("%d%d",&n,&x);for(int i=1;i<=n;i++)scanf("%d%d%d",&lose[i],&win[i],&need[i]);printf("%lld",dfs(0,x)*5); } 錯誤的記憶化搜索

求助路過大佬

轉載于:https://www.cnblogs.com/TheRoadToTheGold/p/6367147.html

總結

以上是生活随笔為你收集整理的DFS——记忆化搜索——动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。