DP

线性dp

 

背包dp

 

恰好装满的背包

P5020 [NOIP2018 提高组] 货币系统

题目背景

NOIP2018 提高组 D1T2

题目描述

在网友的国度中共有 nn 种不同面额的货币,第 ii 种货币的面额为 a[i]a[i],你可以假设每一种货币都有无穷多张。为了方便,我们把货币种数为 nn、面额数组为 a[1..n]a[1..n] 的货币系统记作 (n,a)(n,a)。

在一个完善的货币系统中,每一个非负整数的金额 xx 都应该可以被表示出,即对每一个非负整数 xx,都存在 nn 个非负整数 t[i]t[i] 满足 a[i] \times t[i]a[i]×t[i] 的和为 xx。然而, 在网友的国度中,货币系统可能是不完善的,即可能存在金额 xx 不能被该货币系统表示出。例如在货币系统 n=3n=3, a=[2,5,9]a=[2,5,9] 中,金额 1,31,3 就无法被表示出来。

两个货币系统 (n,a)(n,a) 和 (m,b)(m,b) 是等价的,当且仅当对于任意非负整数 xx,它要么均可以被两个货币系统表出,要么不能被其中任何一个表出。

现在网友们打算简化一下货币系统。他们希望找到一个货币系统 (m,b)(m,b),满足 (m,b)(m,b) 与原来的货币系统 (n,a)(n,a) 等价,且 mm 尽可能的小。他们希望你来协助完成这个艰巨的任务:找到最小的 mm。

输入格式

输入文件的第一行包含一个整数 TT,表示数据的组数。

接下来按照如下格式分别给出 TT 组数据。 每组数据的第一行包含一个正整数 nn。接下来一行包含 nn 个由空格隔开的正整数 a[i]a[i]。

输出格式

输出文件共有 TT 行,对于每组数据,输出一行一个正整数,表示所有与 (n,a)(n,a) 等价的货币系统 (m,b)(m,b) 中,最小的 mm。

输入输出样例

输入 #1
2 
4 
3 19 10 6 
5 
11 29 13 19 17 
输出 #1
2   
5  

说明/提示

在第一组数据中,货币系统 (2, [3,10])(2,[3,10]) 和给出的货币系统 (n, a)(n,a) 等价,并可以验证不存在 m < 2m<2 的等价的货币系统,因此答案为 22。 在第二组数据中,可以验证不存在 m < nm<n 的等价的货币系统,因此答案为 55。

【数据范围与约定】

对于 100\%100% 的数据,满足 1 ≤ T ≤ 20, n,a[i] ≥ 11T20,n,a[i]1。

【思路】

每种物品可以拿多次且正好拿完,是完全背包

1.初始化时f[0]=0,其余为负无穷。

2.进行完全背包

 

分组背包

P1757 通天之分组背包

题目背景

直达通天路·小 A 历险记第二篇

题目描述

自 0101 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 0101 背包,他的物品大致可分为 kk 组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。

输入格式

两个数 m,nm,n,表示一共有 nn 件物品,总重量为 mm。

接下来 nn 行,每行 33 个数 a_i,b_i,c_iai,bi,ci,表示物品的重量,利用价值,所属组数。

输出格式

一个数,最大的利用价值。

输入输出样例

输入 #1
45 3
10 10 1
10 5 1
50 400 2
输出 #1
10

说明/提示

1 \leq m, n \leq 10001m,n1000。

【思路】

题目要求可以用多张货币得到不同的数值

可以将分组背包转化为01背包,从n件物品每个只能选择一次变成了每组物品只能选择一次

 

 

 

树形dp

树形dp可以理解为在树上进行状态转移,一般在dfs的过程中完成dp。

1578:【例 4】战略游戏

【题目描述】

Bob 喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的方法。现在他有个问题。

现在他有座古城堡,古城堡的路形成一棵树。他要在这棵树的节点上放置最少数目的士兵,使得这些士兵能够瞭望到所有的路。

注意:某个士兵在一个节点上时,与该节点相连的所有边都将能被瞭望到。

请你编一个程序,给定一棵树,帮 Bob 计算出他最少要放置的士兵数。

【输入】

输入数据表示一棵树,描述如下。

第一行一个数 <span id="MathJax-Span-2" class="mrow"><span id="MathJax-Span-3" class="mi">NN ,表示树中节点的数目。

第二到第 <span id="MathJax-Span-5" class="mrow"><span id="MathJax-Span-6" class="mi">N<span id="MathJax-Span-7" class="mo">+<span id="MathJax-Span-8" class="mn">1N+1 行,每行描述每个节点信息,依次为该节点编号 <span id="MathJax-Span-10" class="mrow"><span id="MathJax-Span-11" class="mi">ii,数值 <span id="MathJax-Span-13" class="mrow"><span id="MathJax-Span-14" class="mi">kk,<span id="MathJax-Span-16" class="mrow"><span id="MathJax-Span-17" class="mi">kk 表示后面有 <span id="MathJax-Span-19" class="mrow"><span id="MathJax-Span-20" class="mi">kk 条边与节点 <span id="MathJax-Span-22" class="mrow"><span id="MathJax-Span-23" class="mi">ii 相连,接下来 <span id="MathJax-Span-25" class="mrow"><span id="MathJax-Span-26" class="mi">kk 个数,分别是每条边的所连节点编号 <span id="MathJax-Span-28" class="mrow"><span id="MathJax-Span-29" class="msubsup"><span id="MathJax-Span-30" class="mi">r<span id="MathJax-Span-31" class="mn">1<span id="MathJax-Span-32" class="mo">,<span id="MathJax-Span-33" class="msubsup"><span id="MathJax-Span-34" class="mi">r<span id="MathJax-Span-35" class="mn">2<span id="MathJax-Span-36" class="mo">,<span id="MathJax-Span-37" class="mo">⋯<span id="MathJax-Span-38" class="mo">,<span id="MathJax-Span-39" class="msubsup"><span id="MathJax-Span-40" class="mi">r<span id="MathJax-Span-41" class="mi">kr1,r2,⋯,rk 。

对于一个有 <span id="MathJax-Span-43" class="mrow"><span id="MathJax-Span-44" class="mi">NN 个节点的树,节点标号在 <span id="MathJax-Span-46" class="mrow"><span id="MathJax-Span-47" class="mn">00 到 <span id="MathJax-Span-49" class="mrow"><span id="MathJax-Span-50" class="mi">N<span id="MathJax-Span-51" class="mo">&minus;<span id="MathJax-Span-52" class="mn">1N−1 之间,且在输入文件中每条边仅出现一次。

【输出】

输出仅包含一个数,为所求的最少士兵数。

【输入样例】

4
0 1 1
1 2 2 3
2 0
3 0

【输出样例】

1

【提示】

数据范围与提示:

对于 100% 的数据,有 <span id="MathJax-Span-54" class="mrow"><span id="MathJax-Span-55" class="mn">0<span id="MathJax-Span-56" class="mo">&lt;<span id="MathJax-Span-57" class="mi">N<span id="MathJax-Span-58" class="mo">&le;<span id="MathJax-Span-59" class="mn">15000<N≤1500。

【思路】

f[i][1]:放在i,以i为根的子树的士兵数量最小值

f[i][0]:不放在i,以i为根的子树的士兵数量最小值

如果i不放,则他的儿子必须要放

如果i放,则他的儿子可放可不放

f[u][1]=min(f[v][0],f[v][1])+1;//u:根 v:儿子
f[u][0]=f[v][1];

 

 

数位dp

数位dp:考虑数字的每一位

通常问题询问在区间[l,r]满足题目要求的答案,用记忆化搜索

注意:要从高位往低位枚举每一位,因为可以通过高位确定范围(是否在区间内)

posted @   沉静的豆芽菜  阅读(664)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示