博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dp的刷表法和填表法
阅读量:5795 次
发布时间:2019-06-18

本文共 1323 字,大约阅读时间需要 4 分钟。

dp的刷表法和填表法

参考:

动态规划刷表法 - acmer_xue的博客 - CSDN博客

http://blog.csdn.net/qq_30241305/article/details/52198780

 

一.先简单讲下什么是填表法,什么是刷表法。

填表法 :就是一般的动态规划,当前点的状态,可以直接用状态方程,根据之前点的状态推导出来。

刷表法:由当前点的状态,更新其他点的状态。需要注意:只用当每个状态所依赖的状态对它的影响相互独立。

二.通过例题看刷表

链接:

题意:三个数,T表示最大的饱腹值,A表示吃a可以增加的饱腹值,B表示吃b可以增加的饱腹值。ab都有无穷多个。初始状态是0,可以有一次通过喝水,来使饱腹值减少一半(向下取整)的机会。

分析:首先按照一般的动态规划,会有问题。

为什么不能用填表法?

因为当前状态既与之前的状态有关,又与之后的状态有关。当前的状态与dp[ i - a],dp[i - b],dp[i * 2]有关。所以用刷表法,来直接更新状态。

此题中,喝水后的状态可以在喝水的基础上计算。及可以先计算所有喝水前的状态,再计算所有喝水后的状态。喝水前的状态可以更新喝水后的状态。

另:注意,本题中饱腹值不能超过最大值T

代码:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 using namespace std;15 int dp[5000005][2];16 int main()17 {18 //freopen("in.txt","r",stdin);19 int p,a,b;20 scanf("%d%d%d",&p,&a,&b);21 dp[0][0] = dp[0][1] = 1;22 for(int j = 0; j < 2; j ++)23 {24 for(int i = 0; i <= p; i ++)25 {26 if(dp[i][j])27 {28 if(i+ a <= p)29 dp[i + a][j] = 1;30 if(i + b <= p)31 dp[i + b][j] = 1;32 if(j == 0)33 dp[i / 2][1] = 1;34 }35 }36 }37 38 39 int ans;40 for(int i = p; i >= 0; i --)41 {42 if(dp[i][0] || dp[i][1])43 {44 ans = i;45 break;46 }47 }48 printf("%d\n",ans);49 50 return 0;51 }
你可能感兴趣的文章
Windows 8 C++/CX字符串
查看>>
路由协议重分发之RIP协议与OSPF协议
查看>>
C# 操作Excel2003
查看>>
手把手教你自己动手恢复坏道硬盘数据
查看>>
【电子基础】电子基础知识·持续更新
查看>>
mysql创建定时执行存储过程任务
查看>>
heartbeat 3.0集群(1)集群原理
查看>>
C#中 Finally中不允许有return
查看>>
Java - 容器详解
查看>>
Synchronized Using
查看>>
Linux下PF_PACKET的使用(todo)
查看>>
Android开发者指南(16) —— Activity and Task Design
查看>>
linux下在jar包中找类是否存在
查看>>
mysql备份与恢复策略
查看>>
PPT2010设置图片透明度
查看>>
Horizon View 6-配置View Connection Server⑷
查看>>
几个负载均衡器的小结
查看>>
如何识别高级的验证码
查看>>
[PYTHON]python 基础笔记(4)
查看>>
写保护下的U盘修复
查看>>