区间dp 例题
D - 石子合并问题--直线版
HRBUST - 1818
这个题目是一个区间dp的入门,写完这个题目对于区间dp有那么一点点的感觉,不过还是不太会。
注意这个区间dp的定义
dp[i][j] 表示的应该是将连续的从 i 到第 j 堆的石块进行合并的最大值(或者最小值)
知道这个定义就很好求了,所以我们每次都要先枚举这个区间的长度,然后就是枚举这个区间的起点,然后就是枚举分段点。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#define pi acos(-1)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = ;
int dpmax[maxn][maxn], dpmin[maxn][maxn];
int stone[maxn];
int sum[maxn];
int main() {
int n;
while (scanf("%d", &n)!=EOF) {
memset(dpmin, inf, sizeof(dpmin));
memset(dpmax, -inf, sizeof(dpmax));
memset(sum, , sizeof(sum));
for (int i = ; i <= n; i++) {
scanf("%d", &stone[i]);
sum[i] = sum[i - ] + stone[i];
dpmax[i][i] = ;
dpmin[i][i] = ;
}
for (int i = ; i <= n; i++) {
for (int j = ; j + i <= n + ; j++) {
int ends = j + i - ;
for (int k = j; k < ends; k++) {
dpmin[j][ends] = min(dpmin[j][ends], dpmin[j][k] + dpmin[k + ][ends] + sum[ends] - sum[j - ]);
dpmax[j][ends] = max(dpmax[j][ends], dpmax[j][k] + dpmax[k + ][ends] + sum[ends] - sum[j - ]);
}
}
}
printf("%d %d\n", dpmin[][n], dpmax[][n]);
}
return ;
}
区间dp入门
这个要是把题目看清楚了+看了一点点的题解就很简单了。
这个题目需要对题目进行一部分处理,推荐学长博客https://blog.csdn.net/qq_39599067/article/details/80335949
学长博客讲的很清楚了。
我说一下我的理解吧,f[i][j]表示从i到j的异或和,dp[i][j]表示从i到j的最大的异或和
因为f[i][j]=f[i][j+1]^f[i+1][j]
所以这个dp就很好转移了 dp[i][j]=max(f[i][j],max(dp[i][j-1],dp[i+1][j])
这个转移方程我觉得还比较难理解,对于dp[i][j] 应该是由三个状态转移过来的,一个是本身的异或和,一个不包括左端点的最大值,一个是不包括右端点的最大值,
这个可以去看学长的那个图。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 5e3 + ;
int dp[maxn][maxn], f[maxn][maxn]; int main()
{
int n;
scanf("%d", &n);
for(int i=;i<=n;i++)
{
scanf("%d", &dp[i][i]);
f[i][i] = dp[i][i];
}
for(int i=;i<=n;i++)
{
for(int j=;j+i<=n;j++)
{
f[j][j + i] = f[j][j + i - ] ^ f[j + ][j + i];
}
}
for(int i=;i<=n;i++)
{
for(int j=;j+i<=n;j++)
{
dp[j][j + i] = max(f[j][i + j], max(dp[j][j + i - ], dp[j + ][j + i]));
}
}
int q;
scanf("%d", &q);
while(q--)
{
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", dp[l][r]);
}
return ;
}
区间dp
B - Halloween Costumes
这个题目我觉得还是一个比较难的区间dp,相对于这个之前可以说算是裸题了。
这个我看了题解之后,按照题解的思路去敲代码,推荐博客:https://www.cnblogs.com/DOLFAMINGO/p/7927432.html
他是把这个题目进行了一定的转化,转化成了涂色,就是把给定一个区间,每次可以为一段连续的子区间刷一种颜色。问最少需要刷多少次,能得到目标的区间。
该题解对左端点进行讨论,这个算是一个切入点吧,因为对于左端点和右端点进行讨论应该都是可以的,但是对于左端点会更加简单一些。
怎么对左端点进行讨论呢
我的理解:
预处理就是假设每一个都是要涂成不一样的颜色
这个应该是理解为先涂成目标这样子,然后去判断涂了多少层。
对左端点进行考虑。
先假设左端点涂的是一种新颜色。
所以dp[i][j]=dp[i+1][j]+1;
然后去判断这个区间有没有和它一样的颜色,如果有的话,他们应该是同一个时刻涂的,
所以就暂时忽略它,以这个点为分段点对该点左右颜色总和加起来 去最小。
其实看了题解理解我觉得还是挺难的,能想到的人,我感觉挺变态的。
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e2 + ;
int dp[maxn][maxn];
int a[maxn];
int main()
{
int t;
scanf("%d", &t);
for(int cas=;cas<=t;cas++)
{
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
memset(dp, , sizeof(dp));
for (int i = ; i <= n; i++) dp[i][i] = ;
for(int i=;i<=n;i++)
{
for(int j=;j+i-<=n;j++)
{
int ends = i + j - ;
dp[j][ends] = dp[j + ][ends] + ;
for(int k=j+;k<=ends;k++)
{
if(a[j]==a[k])
{
dp[j][ends] = min(dp[j][ends], dp[j][k - ] + dp[k + ][ends]);
}
}
}
}
printf("Case %d: %d\n",cas, dp[][n]);
}
return ;
}
区间dp
H - String painter
来写这个题目,如果你解决了上面的这个题目,那么这个就变得很简单了,
从上面得题目我们知道了怎么去把一个空白字符串涂成我们想要的字符串。
现在我们是把一个已知的字符串涂成我们想要的,这个怎么写呢?
这个应该是去枚举每一位的字符,如果这个字符和所求的字符相同就不需要再涂了,
但是如果不一样就需要给它重新涂色,这个涂色可不是简单的加上一个颜色,
而是要从整体的角度去看如何给她涂色最优,所以我们要枚举这个和这个之前的每一个位置来判断最优。
区间dp
区间dp 例题的更多相关文章
- 区间DP小结 及例题分析:P1880 [NOI1995]石子合并,P1063 能量项链
区间类动态规划 一.基本概念 区间类动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的那些元素合并而来由很大的关系.例如状态f [ i ][ j ],它表示以已合 ...
- 区间dp(模板+例题)
参考博文:区间dp小结(附经典例题) 首先,什么是区间dp?它是干什么的? 先在小区间进行DP得到最优解,然后再利用小区间的最优解合并求大区间的最优解 操作往往涉及到区间合并问题 以上. 模板如下: ...
- 区间dp入门+例题
区间dp作为线性dp的一种,顾名思义是以区间作为阶段进行dp的,使用它的左右端点描述每个维度,决策往往是从小状态向大状态转移中推得的.它跟st表等树状结构有着相似的原理---向下划分,向上递推. dp ...
- 紫书 例题 9-9 UVa 10003 (区间dp+递推顺序)
区间dp,可以以一个区间为状态,f[i][j]是第i个切点到第j个切点的木棍的最小费用 那么对于当前这一个区间,枚举切点k, 可以得出f[i][j] = min{dp(i, k) + dp(k, j) ...
- 区间dp的典例
区间dp, 属于dp的一种,顾名思义,便是对区间处理的dp,其中石子归并,括号匹配,整数划分最为典型. (1)石子归并 dp三要素:阶段,状态,决策. 首先我们从第i堆石子到第j堆石子合并所花费的最小 ...
- LightOJ1033 Generating Palindromes(区间DP/LCS)
题目要计算一个字符串最少添加几个字符使其成为回文串. 一年多前,我LCS这道经典DP例题看得还一知半解时遇到一样的问题,http://acm.fafu.edu.cn/problem.php?id=10 ...
- LightOJ1025 The Specials Menu(区间DP)
给一个字符串,问有几种删字符的方式使删后的非空字符串是个回文串. 当然区间DP:dp[i][j]表示子串stri...strj的方案数 感觉不好转移,可能重复算了.我手算了"AAA" ...
- 区间DP(总结)
学长一晚上的耐心讲解,使我明白区间DP这么高级的东西,还是挺容易的.也就是在一段区间内的动态规划. 下面用例题进行总结. 例题:石子归并. 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石 ...
- 区间DP的学习(持续更新)
例题: 1.Multiplication Puzzle 原题地址:http://poj.org/problem?id=1651 2.Dire Wolf 原题地址:http://acm.split.hd ...
随机推荐
- centos7安装MariaDB以及Failed to start mariadb.service: Unit not found的错误解决
centos7下yum安装MariaDB CentOS 7下mysql下替换成MariaDB了.MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权 许可 Mari ...
- spring 中 hibernate 的 2种 配置方式(新旧 2种方式)
Spring对hibernate配置文件hibernate.cfg.xml的集成,来取代hibernate.cfg.xml的配置 Spring对hibernate配置文件hibernate.cfg.x ...
- Python 文件拼接
# -*- coding:utf-8 -*- import re import csv file = open('make_setup.cfg', 'w+') with open("tyb. ...
- 动手学Transformer
动手实现Transformer,所有代码基于tensorflow2.0,配合illustrated-transformer更香. 模型架构 Encoder+Decoder Encoder Decode ...
- Python队列的三种队列方法
今天讲一下队列,用到一个python自带的库,queue 队列的三种方法有: 1.FIFO先入先出队列(Queue) 2.LIFO后入先出队列(LifoQueue) 3.优先级队列(PriorityQ ...
- ORCAD常用元件库说明
以下是ORCAD自带库文件的说明,路径:Cadence\Cadence_SPB_16.6\tools\capture\library 1' AMPLIFIER.OLB共182个零件,存放模拟放大器IC ...
- 一站式WebAPI与认证授权服务
保护WEBAPI有哪些方法? 微软官方文档推荐了好几个: Azure Active Directory Azure Active Directory B2C (Azure AD B2C)] Ident ...
- O - Navigation System CodeForces - 1321D
题目大意:有一个导航系统,会根据你当前的位置,规划到目的地的最短路线,给你一个有向图,和一条行驶路径,问你导航重新规划路径的最大次数和最小次数. 读题的时候题意特别不理解,何为最大次数,何为最小次数? ...
- Python生成一维码
参考页面 https://pypi.org/project/python-barcode/ 利用python-barcode的库 一.安装python-barcode库 #安装前提条件库 pip in ...
- 今天我们来谈谈绝对定位和相对定位的区别,和需要注意的问题;position:absolute|relative;
首先position:absolute|relative; 前者是绝对定位,后者是相对定位: position属性的四个值: static,relative,fixed,absolute; 重点重点重 ...