以洛谷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——记忆化搜索——动态规划相关推荐

  1. 递归 dfs 记忆化搜索 动态规划

    今天做洛谷P1434 [SHOI2002]滑雪 的时候仔细想了想记忆化搜索 现在总结一下 为了描述问题的某一状态,必须用到该状态的上一状态,而描述上一状态,又必须用到上一状态的上一状态--这种用自已来 ...

  2. UVA10285 Longest Run on a Snowboard【DFS+记忆化搜索】

    Michael likes snowboarding. That's not very surprising, since snowboarding is really great. The bad ...

  3. dfs记忆化搜索(带限制的选择问题) 讲解:LeetCode打家劫舍||| / 蓝桥 地宫取宝/蓝桥 k进制数//剪格子//方格分割

    记忆化递归的必要性: 普通的递归可能会重复求解某一值,类似斐波那契数列.同样的子问题可能会被求解多次,这样就会很慢很慢很慢 解决方法:我们把历史求解(子问题)记录下来,如果下次需要求解子问题,那么直接 ...

  4. [蓝桥杯]算法提高 第二点五个不高兴的小明(记忆化搜索||动态规划)

    问题描述 有一条长为n的走廊,小明站在走廊的一端,每次可以跳过不超过p格,每格都有一个权值wi. 小明要从一端跳到另一端,不能回跳,正好跳t次,请问他跳过的方格的权值和最大是多少? 输入格式 输入的第 ...

  5. 8636 跳格子(dfs+记忆化搜索)

    8636 跳格子 该题有题解 时间限制:2457MS  内存限制:1000K 提交次数:139 通过次数:46 题型: 编程题   语言: G++;GCC Description 地上有一个n*m 的 ...

  6. ZOJ - 2972 Hurdles of 110m(记忆化搜索/动态规划)

    题目链接:点击查看 题目大意:给定n个点,以及m的最大体力值,共有三个状态通过每个点 快速模式:消耗时间t1,消耗体力f1 匀速模式:消耗时间t2 慢速模式:消耗时间t3,恢复体力f2 问:通过n个点 ...

  7. 牛客假日团队赛5 F 随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)...

    链接:https://ac.nowcoder.com/acm/contest/984/F 来源:牛客网 随机数 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...

  8. [Leetcode][第322题][JAVA][零钱兑换][回溯][记忆化搜索][动态规划]

    [问题描述][中等] [解答思路] 1. 递归(超时) class Solution {int res = Integer.MAX_VALUE;public int coinChange(int[] ...

  9. POJ1088 Bailian1088 滑雪【DFS+记忆化搜索】

    滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 114685 Accepted: 43807 Description Mic ...

最新文章

  1. python中nlp的库_单词袋简介以及如何在Python for NLP中对其进行编码
  2. django 设置外键_django2.0前后版本定义外键和一对一关系的差别
  3. Asp.Net获取客户端信息-学习中
  4. 十一、Redis五大数据类型之三Set
  5. ext的window如何隐藏水平滚动条
  6. hdu 1874 畅通工程续(模板题 spfa floyd)
  7. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1051:分段函数
  8. 在VUE中利用MQTT协议实现即时通讯
  9. rar x64 5.50 linux,WinRAR 5.50 简体中文正式版发布
  10. React 向children中传值,layouts
  11. 红帽linux 竞争对手,为什么红帽不把CentOS当作竞争对手?
  12. 利用计算机测地震是计算机的什么,计算机在气象预报、地震探测、导弹卫星轨迹等方面的应用都属于( )...
  13. “内存不足”的九大原因及解决方法
  14. python set() 和 dict()
  15. bzoj3620 似乎在梦中见过的样子
  16. LINUX下载编译x265
  17. 南京工业大学计算机科学与技术学院保研外校,南京工业大学计算机科学与技术学院2018年招收推荐免试研究生章程...
  18. google 常用的技术搜索关键词
  19. 哈工大计算机科学与技术邬向前,人工智能学院组队赴哈工大交流学习
  20. c语言编译器w7,wintc下载|c语言编译器wintc win7/win8兼容版 v2.0下载 64位32位 - 3322软件站...

热门文章

  1. pythondocx批量提取目录及内容_一个可以选择目录生成doc目录内容的小工具(三) -python-docx...
  2. mysql数据库分表备份脚本_MySQL分库分表备份脚本
  3. 计算机图形学多边形填充代码_零基础学计算机图形学太难?或许你缺的只是一本好书...
  4. linux+网卡驱动社区,Linux下如何确定网卡所使用的驱动程序
  5. arcgis java api_Arcgis API For Javascript下载与安装
  6. 深度 | 阿里云蒋江伟:什么是真正的云原生?
  7. Kubernetes 核心概念
  8. 解锁云原生 AI 技能 - 开发你的机器学习工作流
  9. linux ftp iptables,linux – IPTABLES允许ssh,ftp,pop等从一个静态...
  10. razor 怎样使用session变量_Nginx负载均衡解决session一致性问题