线性DP

考虑一组硬币面值 1,5,11 给定W,求凑出W的最少硬币个数

我们记凑出n需要用到的最少硬币数量为f(n)   我们注意到了一个很棒的性质 : f(n)只与f(n-1) f(n-5) f(n-11) 有关。

更确切的说f(n)=min(f(n-1),f(n-5),f(n-11)}+1

int f[], cost;
int main() {
int n;
scanf("%d", &n);
f[] = ;
for (int i = ; i <= n; i++) {
cost = INF;
if (i - >= ) cost = min(cost, f[i - ] + );
if (i - >= ) cost = min(cost, f[i - ] + );
if (i - >= ) cost = min(cost, f[i - ] + );
f[i] = cost;
printf("f[%d]=%d\n", i, f[i]);
}
}

这个做法的原理是:

--f(n)只与f(n-1),f(n-5),f(n-11)相关

--我们只关心f(w)的值,不关心怎么取到W的

这就是DP,将一个问题拆成几个子问题,分别求解这些子问题,即可推断大问题的解

大问题的最优解可以由小问题的最优解推出,这个性质叫“最优子结构性质”。

用DP的情况

--能将大问题拆成小问题

--无后效性

--最优子结构性质

DP核心思想:尽量缩小可能解空间

首先把面对的局面表示为x,称为设计状态

对于状态x,记我们要求出的答案为f(x),目标是求出f(T)   找出f(x)与哪些局面有关,写出一个式子(称为状态转移方程)通过f(p)推出f(x)

最长上升子序列 (LIS)

设计状态:记f(x)为以ax结尾的LIS长度,那么答案就是max{f(x)}   

状态转移:考虑比x小的每一个p,如果ax>af(x)可取f(p)+1

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
//LIS
int n;
int a[], f[]; int main() {
scanf("%d", &n);
for (int i = ; i < n; i++) scanf("%d", &a[i]);
int Max;
for (int i = ; i < n; i++) {
f[i] = ;
for (int j = ; j < i; j++) {
if (a[i] > a[j]) f[i] = max(f[i], f[j] + );
}
Max = max(Max, f[i]);
}
printf("%d", Max);
return ;
}

 LCS

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
//LCS
int dp[][];
string x, y;
int l1, l2;
int main() {
cin >> x >> y;
int l1 = x.length();
int l2 = y.length();
for (int i = ; i <=l1; i++) {
for (int j = ; j <=l2; j++) {
if (x[i-] == y[j-]) dp[i][j] = dp[i - ][j - ] + ;
else dp[i][j] = max(dp[i - ][j], dp[i][j - ]);
}
}
cout << dp[l1][l2];
return ;
}

洛谷P1020 导弹拦截

1.最长不上升序列长度

2.最长上升序列长度

code:

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<stack>
#include<cctype>
const double PI = acos(-1.0);
#define eps 1e-6
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std; const int maxn = ; int a[maxn], d1[maxn], d2[maxn];
int n; int main() {
while (~scanf("%d", &a[n++]));
int len1 = , len2 = ;
d1[] = a[], d2[] = a[];
for (int i = ; i < n-; i++) {
if (d1[len1] >= a[i]) d1[++len1] = a[i];
else {
d1[upper_bound(d1, d1 + len1+, a[i], greater<int>()) - d1] = a[i];
}
if (d2[len2] < a[i]) d2[++len2] = a[i];
else {
d2[lower_bound(d2, d2 + len2+, a[i]) - d2] = a[i];
}
}
//for (int i = 0; i < len1; i++) printf("%d ", d1[i]);
//for (int i = 0; i < len2; i++) printf("%d ", d2[i]);
printf("%d\n%d", len1 + , len2 + );
return ;
}

HZNU-ACM寒假集训Day6小结 线性DP的更多相关文章

  1. HZNU-ACM寒假集训Day7小结 背包DP

    背包问题 01背包 状态:f(i,j) 表示只能装前i个物品的情况下,容量为j的背包所能达到的最大总价值 状态转移方程:  f(i,j)=max(f(i-1,j),f(i-1,j-w[i])+v[i] ...

  2. 中南大学2019年ACM寒假集训前期训练题集(基础题)

    先写一部分,持续到更新完. A: 寒衣调 Description 男从戎,女守家.一夜,狼烟四起,男战死沙场.从此一道黄泉,两地离别.最后,女终于在等待中老去逝去.逝去的最后是换尽一生等到的相逢和团圆 ...

  3. HZNU-ACM寒假集训Day10小结 树-树形DP

    树形DP 加分二叉树 洛谷P1040 注意中序遍历的特点:当根节点编号k时,编号小于k的都在其左子树上,编号大于k的都在右子树 转移方程 f[i,j]=max{f[i,k-1]*f[k+1,j]+d[ ...

  4. 【LOJ6074】【2017 山东一轮集训 Day6】子序列 DP

    题目描述 有一个由前 \(m\) 个小写字母组成的串 \(S\),有 \(q\) 个询问,每次给你 \(l,r\),问你 \(S_{l\ldots r}\) 有多少个非空子序列. \(m=9,n=\l ...

  5. 中南大学2019年ACM寒假集训前期训练题集(入门题)

    A: 漫无止境的八月 Description 又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500 ...

  6. HZNU-ACM寒假集训Day8小结 最小生成树

    最小生成树(无向图) Kruskal 给所有边按从小到大排序 形成环则不选择(利用并查集) P1546 最短网络   https://www.luogu.com.cn/problem/P1546 #i ...

  7. HZNU-ACM寒假集训Day3小结 搜索

    简单搜索 1.DFS UVA 548 树 1.可以用数组方式实现二叉树,在申请结点时仍用“动态化静态”的思想,写newnode函数 2.给定二叉树的中序遍历和后序遍历,可以构造出这棵二叉树,方法是根据 ...

  8. HZNU-ACM寒假集训Day1小结 STL 并查集

    常用STL 1.优先队列 priority_queue 内部是用堆(heap)实现的 priority_queue<int> pq; 默认为一个“越小的整数优先级越低的优先队列” 对于一些 ...

  9. 2022寒假集训day6

    day6上午还是做四道题T1区域[上机练习]1.编程计算由"*"号围成的下列图形的面积.面积计算方法是统计*号所围成的闭合曲线中水平线和垂直线交点的数目.如下图所示,在 10*10 ...

随机推荐

  1. Task使用注意

    1. CancellationTokenSource的使用 https://binary-studio.com/2015/10/23/task-cancellation-in-c-and-things ...

  2. ubuntu 系统分配固定 ip--

    由于Ubuntu重启之后,ip很容易改变,可以用以下方式固定ip地址 1.设置ip地址 vi /etc/network/interface # The loopback network interfa ...

  3. JMeter学习-图形化 HTML 报表概要说明

    JMeter 3.0开始支持动态生成图形化 HTML dashboard报告,当前生成报告有一下两种方式: 1.脚本测试执行结束后,即生成HTML测试报告 2.通过之前生成的测试结果,生成HTML测试 ...

  4. Linux 补丁 的简单使用: 制作补丁,打补丁,撤销补丁

    ​ 背景: 补丁的使用对于嵌入式开发人员来说,在维护或者开发中都比较方便. 制作补丁: diff - 逐行比较文件. 格式: diff 参数 旧文件/旧文件夹 新文件/新文件夹 (注意顺序 新旧文件夹 ...

  5. Windows系统查看端口被那些进程使用

    Windows系统查看端口被那些进程使用注:当前Windows为虚拟机环境1. 打开命令提示符:开始-运行-cmd2. 列出使用端口的PID: netstat -abno -a 显示所有连接和侦听端口 ...

  6. Java提升三:函数式接口

    1. 定义 函数式接口即是有且仅有一个抽象方法的接口. 注意: (1)函数式接口只对于抽象方法有要求,对于接口中的默认方法,静态方法,私有方法数量并不作特殊要求. (2)既然函数式接口定义了抽象方法, ...

  7. 08.swoole学习笔记--异步tcp客户端

    <?php //创建异步tcp客户端 $client=new swoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_ASYNC); //注册连接成功的回调函数 $c ...

  8. postman 请求get post方法的 区别

    1.HTTP的五种请求方法:GET, POST ,HEAD,OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法. GET请求:请求指定的页面信息,并返回实体主体.(通常用 ...

  9. Microsoft Windows 实用程序 Sysinternals Utilities Index

    最新页面时间:2017年5月16日 Sysinternals被MS收购--windows internals共近70多个工具集 Sysinternals套件 整套Sysinternals Utilit ...

  10. NO5 grep-head-tail命令

    ·*****grep:#过滤需要的内容(linux三剑客).                   -v:排除内容.eg:grep -v oldboy test.txt ·head: #头,头部.读取文 ...