PJ可能会用到的动态规划选讲-学习笔记

by Pleiades_Antares

难度和速度全部都是按照普及组来定的咯

数位状压啥就先不讲了

这里主要提到的都是比较简单的DP

一道思维数学巧题(补昨天)

先看一道外文题目:

(简单翻译稍微改了下,原题目戳我

现在PA要放技能,要放n(10e9)个技能,

但是放技能有冷却时间,x秒才能放一次。

PA有两个事情可以做:

  1. 有m个天赋可以学习,第i个天赋要花b[i]块钱,作用是把冷却时间改为a[i]。
  2. 可以找个打手,有k个打手可以找,请第i个打手需要花掉d[i]块钱,他会直接帮你放c[i]次技能。

m, k 10e5

给出初始金钱数,问所用的最少时间。

注意天赋最多只能学习一个,打手最多只能请一位。

拿到题目以后,我们首先要想:这道题用什么方法来做?(比如贪心,dp等等)

首先:

要枚举选择学哪个天赋 (此时我们还剩下C块钱)

然后下一步➡️找到用哪个打手比较好。



看这张图,贪心显然是不行的。

那当我们枚举完以后怎么才能选择打手呢?

——什么情况下我们绝对不会选择x这个打手

——当且仅当:有人比x便宜且比x能干活

啥时候可以贪心呢?

我们把那种又贵又不好用“名不副实”的打手给排除掉

直接对打手按照花费排序,然后如果某个打手前面有(说明比他便宜)比他能干的,那么就说明这个人名不副实。

这样排除了以后,单调的时候,➡️打手越贵就越好用

这个时候我们再选择自己能力范围内能够买到的最贵的打手就可以了哇

此时处理非常容易,二分查找就直接ok

ll les(ll p)
{
// printf("you can use %lld to less %lld\n",(*--upper_bound(ok.begin(),ok.end(),hero(0,p))).d,(*--upper_bound(ok.begin(),ok.end(),hero(0,p))).c);
return (*(--upper_bound(ok.begin(),ok.end(),hero(0,p)))).c;
}

上面为二分查找orz rxz大佬写的我们这种蒟蒻就好好写正常的二分查找好了qwq

rxz大佬代码:

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll; ll a[100005],b[100005];
ll n,m,k,x,s; struct hero
{
ll c,d;
friend bool operator < (hero a,hero b)
{
return a.d<b.d;
}
hero(ll _c=0,ll _d=0) {c=_c,d=_d;}
};
hero h[100005];
vector <hero> ok; void inp()
{
ll i; memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(h,0,sizeof(h));
ok.clear(); scanf("%lld%lld%lld%lld%lld",&n,&m,&k,&x,&s); for(i=1;i<=m;i++)
scanf("%lld",&a[i]);
for(i=1;i<=m;i++)
scanf("%lld",&b[i]);
for(i=1;i<=k;i++)
scanf("%lld",&h[i].c);
for(i=1;i<=k;i++)
scanf("%lld",&h[i].d);
} void gao()
{
ll i,now=0; sort(h+1,h+1+k); ok.push_back(hero(0,0)); for(i=1;i<=k;i++)
{
if(h[i].c<=now) continue;
now=max(now,h[i].c); ok.push_back(h[i]);
}
} ll les(ll p)
{
// printf("you can use %lld to less %lld\n",(*--upper_bound(ok.begin(),ok.end(),hero(0,p))).d,(*--upper_bound(ok.begin(),ok.end(),hero(0,p))).c);
return (*(--upper_bound(ok.begin(),ok.end(),hero(0,p)))).c;
} ll calc()
{
ll i,t,ans=9000000000000000233; a[0]=x,b[0]=0; for(i=0;i<=m;i++) //use talent i
if(s>=b[i])
{
if(n-les(s-b[i])>0) t=(n-les(s-b[i]))*a[i];
else t=0;
// printf("Use talent %lld t=%lld\n",i,t); ans=min(ans,t);
} printf("%lld\n",ans);
} void work()
{
inp();
gao();
calc();
} int main(void)
{
ll t;
scanf("%lld",&t); while(t--)
work(); return 0;
}

DP选讲

DP是啥?

简单来说——哲学三连

我是谁? 【设计状态】

我从哪里来? 【从之前状态设计转移】

我到哪里去? 【向之后状态设计转移】

热身:钢条切割

钢条长度为n,可以切割。

最后,对于每个长度k,有对应价值w[k]。

问切割结束以后,所有钢条的价值和最大是多少。

辅助理解灵魂绘图:

首先,按照哲学三连来分析一下。

状态:dp[i]表示在i剁了一刀,[1,i]这段区间产生的最大价值。

从哪里来:对于所有的k,dp[i-k]都能到达dp[i]

转移方程:dp[i]=max{dp[i-k+w[k]}

一些历年的NOIP普及组题目讲解

题表见此:

P1002:过河卒

状态: dp[i][j]表示路径数

dp[i][j]可以从dp[i-1][j],dp[i][j-1]这里来

转移方程:dp[i][j]=dp[i-1][j]+dp[i][j-1]

考虑马

被马控制的点为0(不可能走到)

写一个特判:如果被控制那么就是0,否则就是刚才的那个转移方程。

过河卒属于是非常非常容易的一个dp,在考场上一定要能写出来。

P1048 采药

设计状态

dp[v]表示容量为v,装的最大价值 (有后效性)(无后效性是指:某阶段的状态一旦确定,则此后过程的演变不再受此前各状态及决策的影响)

如果一个东西有后效性,把这个东西放进dp数组的下标往往可以消除后效性。

dp[k][v] 用时为v,考虑[1,k]的药。这样就可以排除其后效性。

我是谁:

dp[k][t]考虑了前k个药,用时恰好为t,所取得的最大价值。

我从哪里来:

1⃣️k这个药没有采 dp[k-1][t]

2⃣️k这个药采了 dp[k-1][t-a[k]]+w[k] 之前用掉的时间就是t-a[k],(用a[k]的时间来采这个药)(付出了时间得到了价值)(

(3⃣️dp[k][t-1]来)

然后取一个max就做出来题目了。

单调队列

给一个数组a和一个正整数k

对于每一个长度为k的区间,求出这个区间内的最大值。







——如果一个选手比你小,还比你强,那你就打不过他了。(比如说洛谷新一代吉祥物chen_zhe先生)


题目


Dice Game

// https://vjudge.net/problem/Gym-101502D

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std; // dp[n][k] : score=n , k is up int dp[10005][7]; void move(int n,int k)
{
int ans,i,j; for(i=1;i<=6;i++)
if(i!=k && i+k!=7)
dp[n+i][i]=min(dp[n+i][i],dp[n][k]+1);
} void calc()
{
int i,j; for(i=0;i<=10002;i++)
for(j=1;j<=6;j++)
dp[i][j]=23333333; dp[0][1]=0; for(i=0;i<=10002;i++)
for(j=1;j<=6;j++)
move(i,j);
} void get()
{
int x,i,ans=23333333;
scanf("%d",&x);
for(i=1;i<=6;i++)
ans=min(ans,dp[x][i]);
printf("%d\n",ans==23333333?-1:ans);
} int main(void)
{
int t;
calc(); scanf("%d",&t);
while(t--)
get(); return 0;
}

考前训练(复习)指南











只要你开的空间爆了不管你有没有用那么多都是一个死

PJ可能会用到的动态规划选讲-学习笔记的更多相关文章

  1. MySQL实战45讲学习笔记:第三十九讲

    一.本节概况 MySQL实战45讲学习笔记:自增主键为什么不是连续的?(第39讲) 在第 4 篇文章中,我们提到过自增主键,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧 ...

  2. 深挖计算机基础:MySQL实战45讲学习笔记

    参考极客时间专栏<MySQL实战45讲>学习笔记 一.基础篇(8讲) MySQL实战45讲学习笔记:第一讲 MySQL实战45讲学习笔记:第二讲 MySQL实战45讲学习笔记:第三讲 My ...

  3. MySQL实战45讲学习笔记:事务隔离级别(第三讲)

    一.隔离性与隔离级别 1.事务的特性 原子性 一致性 隔离性 持久性 2.不同事务隔离级别的区别 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到.读已提交:别人改数据的事务已经提交,我在我 ...

  4. MySQL实战45讲学习笔记:第二十五讲

    一.引子 在上一篇文章中,我和你介绍了 binlog 的基本内容,在一个主备关系中,每个备库接收主库的 binlog 并执行. 正常情况下,只要主库执行更新生成的所有 binlog,都可以传到备库并被 ...

  5. MySQL实战45讲学习笔记:第九讲

    一.今日内容概要 今天的正文开始前,我要特意感谢一下评论区几位留下高质量留言的同学.用户名是 @某.人 的同学,对文章的知识点做了梳理,然后提了关于事务可见性的问题,就是先启动但是后提交的事务,对数据 ...

  6. MySQL实战45讲学习笔记:第十讲

    一 .本节内容概要 前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的.但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引.也就是说,使用哪个索引是由MySQL ...

  7. MySQL实战45讲学习笔记:第十三讲

    一.引子 经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变? 那么今天,我就和你聊聊数据库表的空间回收,看看如何解决这个问题. 这里,我们还是针对 ...

  8. 动态规划 Dynamic Programming 学习笔记

    文章以 CC-BY-SA 方式共享,此说明高于本站内其他说明. 本文尚未完工,但内容足够丰富,故提前发布. 内容包含大量 \(\LaTeX\) 公式,渲染可能需要一些时间,请耐心等待渲染(约 5s). ...

  9. MySQL实战45讲学习笔记:日志系统(第二讲)

    一.重要的日志模块:redo log 1.通过酒店掌柜记账思路刨析redo log工作原理 2.InnoDB 的 redo log 是固定大小的 只要赊账记录在了粉板上或写了账本上,之后即使掌柜忘记了 ...

随机推荐

  1. 从零开始学 Web 之 BOM(一)BOM的概念,一些BOM对象

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... +-------------------------------------------------------- ...

  2. JS截取字符串substr 和 substring方法的区别

    substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 ...

  3. SQL不重复查找数据及把一列多行内容拼成一行

    如下表: 表名:Test ID RowID Col1 Col2 1 1 A A 2 1 B A 3 1 A B 4 1 C B 1,查找表中字段重复的只查找一次 select distinct Col ...

  4. jQuery基础教程

    1.使用$()函数 $()函数其实是创建了一个jQuery对象. 这个函数接受CSS选择符作为参数,充当一个工厂, 返回包含页面中对应元素的jQuery对象. 所有能在样式表中使用的选择符都可以传给这 ...

  5. 一款非常好用的万能本地离线激活工具,支持Office2016、Office2015、Win7、Win8/8.1/10、Win2008/2012/R2系统,全自动安装且无需联网状态即可全部激活,它由国外网友heldigard制作,小巧、简单,只需运行而不用去管它自动激活,能自动激活为180天无限循环,欢迎大家下载使用

    office2016激活工具(KMS)是一款非常好用的万能本地离线激活工具,支持Office2016.Office2015.Win7.Win8/8.1/10.Win2008/2012/R2系统,全自动 ...

  6. nexus-3.2.0-01.zip安装以及如何启动服务

    1. 在之前的版本中,启动nexus服务都是在cmd中输入 nexus install来安装服务,nexus start来启动服务. 2. 在nexus-3.2.0-01中,直接在nexus根目录下的 ...

  7. Paired t-test

    1 Continuous Dependent Variable with normal distribution 1 (2 Level) Categorical Independent Variabl ...

  8. 深入理解Java 8 Lambda(语言篇)

    State of Lambda by Brian Goetz 原文链接:http://lucida.me/blog/java-8-lambdas-insideout-language-features ...

  9. NIO 学习笔记三:DatagramChannel

    Java NIO中的DatagramChannel是一个能收发UDP包的通道.因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入.它发送和接收的是数据包. 打开 DatagramChann ...

  10. js 将内容复制到剪切板上

    clipboard是将内容复制到电脑的剪切板上,要引入clipboard.js //将'data-clipboard-text' 样式添加到指定的元素上 $("#effects") ...