区间DP入门题目合集
//mst(dp,0) 初始化DP数组
for(int i=;i<=n;i++)
{
dp[i][i]=初始值
}
for(int len=;len<=n;len++) //区间长度
for(int i=;i<=n;i++) //枚举起点
{
int j=i+len-; //区间终点
if(j>n) break; //越界结束
for(int k=i;k<j;k++) //枚举分割点,构造状态转移方程
{
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+][j]+w[i][j]);
}
}
4
1
2
3
4
Sample Output
19
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = + ;
#define INF 0x3f3f3f3f int main()
{
int n;
scanf("%d", &n);
int sum[maxn];
int f[maxn][maxn];
memset(f, , sizeof(f)); for (int i = ; i <= n; i++)
{
int x;
scanf("%d", &x);
sum[i] = sum[i-]+x;
} for (int len = ; len <= n; len++)
{
for (int i = ; i <= n; i++)
{
int j = i+len-;
f[i][j] = INF;
for (int k = i; k < j; k++)
f[i][j] = min(f[i][j], f[i][k]+f[k+][j] + sum[j] - sum[i-]);
}
} printf("%d\n", f[][n]);
}
题意:
有一根长度为 n 的木棍,m 个可以切开的位置。
如果把一个长木棍切成两根短木棍,那么花费就是那根长木棍的长度。
求把这根木棍按照 m 个切点全部切开的最小花费。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 100 + 100
#define INF 0x3f3f3f3f int main()
{
int n, m;
while(scanf("%d%d", &n, &m) == && n)
{
int x[maxn];
for (int i = ; i <= m; i++)
scanf("%d", &x[i]); x[] = , x[m+] = n; int f[maxn][maxn];
for (int i = ; i <= m+; i++)
{
for (int j = ; j <= m+; j++)
f[i][j] = INF;
f[i][i+] = ;
} for (int len = ; len <= m+; len++)
for (int i = ; i+len <= m+; i++)
{
int j = i+len;
for (int k = i+; k < j; k++)
f[i][j] = min(f[i][k] + f[k][j] + x[j] - x[i], f[i][j]);
} printf("The minimum cutting is %d.\n", f[][m+]);
}
}
![](https://images2018.cnblogs.com/blog/1368114/201808/1368114-20180807152032993-1534552484.png)
样例中,四个能量珠分别为(2, 3) (3, 5) (5, 10) (10, 2)
对于环形区间,我们只要把它展开成线形区间进行DP,然后取 dp[i, i+n-1] 中的最大值就可以了。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std; #define maxn 200 + 100
#define INF 0x3f3f3f3f int main()
{
int n;
while(~scanf("%d", &n))
{
int a[maxn], sum[maxn], f[maxn][maxn];
memset(sum, , sizeof(sum)); for (int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
a[n+i] = a[i];
}
a[*n+] = a[]; for (int i = ; i <= *n; i++)
for (int j = i; j <= *n; j++)
f[i][j] = ; for (int len = ; len <= *n; len++)
for (int i = ; i+len- <= *n; i++)
{
int j = i+len-;
for (int k = i; k < j; k++)
f[i][j] = max(f[i][j], f[i][k] + f[k+][j] + a[i]*a[k+]*a[j+]);
} int ans = ;
for (int i = ; i <= n; i++)
ans = max(ans, f[i][i+n-]); printf("%d\n", ans); } }
也是普通的环形区间DP,拆环为链。
然而这样过不了的。因为数据范围是2000,n^3的DP会TLE。
所以需要用平行四边形优化。
这个玩意我还没有看懂,只是拿过来用。以后慢慢理解。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std; #define maxn 2000 + 100
#define INF 0x3f3f3f3f int main()
{
int n;
while(~scanf("%d", &n))
{
int a[maxn], sum[maxn], f[maxn][maxn], s[maxn][maxn];
memset(sum, , sizeof(sum)); for (int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
a[n+i] = a[i];
} for (int i = ; i <= *n; i++)
sum[i] = sum[i-] + a[i]; for (int i = ; i <= *n; i++)
{
f[i][i] = ;
s[i][i] = i; //这里的s数组也要初始化
for (int j = i+; j <= *n; j++)
f[i][j] = INF;
} for (int len = ; len <= *n; len++)
for (int i = ; i+len- <= *n; i++)
{
int j = i+len-;
for (int k = s[i][j-]; k <= s[i+][j]; k++) //单调性枚举
{
int tmp = f[i][k] + f[k+][j] + sum[j] - sum[i-];
if (tmp < f[i][j])
{
f[i][j] = tmp;
s[i][j] = k;
}
}
} int ans = INF;
for (int i = ; i <= n; i++)
ans = min(ans, f[i][i+n-]); printf("%d\n", ans); } }
区间DP入门题目合集的更多相关文章
- react-native 入门资源合集
# 了解react-native React Native enables you to build world-class application experiences on native pla ...
- LightOJ 1422:Halloween Costumes(区间DP入门)
http://lightoj.com/volume_showproblem.php?problem=1422 题意:去参加派对,有n场派对,每场派对要穿第wi种衣服,可以选择外面套一件,也可以选择脱掉 ...
- spark 入门教程合集
看到一篇不错的 spark 入门教程的合集,在此记录一下 http://www.cnblogs.com/shishanyuan/p/4699644.html
- 树形DP入门题目推荐以及解析
关于树形DP几道入门题目 今天恶补树形DP,感觉海星. 其实挺简单的. 介绍几道例题,我会的. 1.洛谷P1352 没有上司的舞会 我的一篇题解 我们可以考虑每一个节点都是有两种情况. 一个是被邀请: ...
- POJ 2955 Brackets (区间dp入门)
Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...
- 【DP】区间DP入门
在开始之前我要感谢y总,是他精彩的讲解才让我对区间DP有较深的认识. 简介 一般是线性结构上的对区间进行求解最值,计数的动态规划.大致思路是枚举断点,然后对断点两边求取最优解,然后进行合并从而得解. ...
- hdu 4570 Multi-bit Trie 区间DP入门
Multi-bit Trie 题意:将长度为n(n <= 64)的序列分成若干段,每段的数字个数不超过20,且每段的内存定义为段首的值乘以2^(段的长度):问这段序列总的内存最小为多少? 思路: ...
- POJ2955--Brackets 区间DP入门 括号匹配
题意很简单,就是求给出串中最大的括号匹配数目.基础题,格式基本为简单区间dp模板. #include<iostream> #include<string.h> using na ...
- HRBUST - 1818 石子合并 区间dp入门
有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...
随机推荐
- aliyun maven repository
<mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> & ...
- nginx-1.12.2编译安装指导
nginx-1.12.2编译安装 下载源码包 安装 安装后配置 下载源码包 下载地址:http://nginx.org/en/download.html nginx-1.12.2:http://ngi ...
- ABI与编译器:ABI是由内核和工具链定义和实现的
http://book.51cto.com/art/201412/460857.htm <Linux系统编程(第2版)>第1章入门和基本概念,这一章着眼于Linux系统编程的基础概念并从程 ...
- 并查集,是否成树,Poj(1308)
思路: 对于每一条新的边的两个端点,是否是属于一颗树,要是的话,就不是一颗树.否则,就合并. 这里要注意的是,不能是森林,我这里WA了两次了.只不过在最后,查看每个节点的祖先是否是同一个就可以了. # ...
- Max answer(The Preliminary Contest for ICPC China Nanchang National Invitational)
Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values ...
- Linux下内存的几个基本概念
先介绍几个基本概念: SIZE: 进程使用的地址空间, 如果进程映射了100M的内存, 进程的地址空间将报告为100M内存. 事实上, 这个大小不是一个程序实际使用的内存数. RSS: "R ...
- bootstrap suggest搜索建议插件
近日因工作需要看了下此插件. 首先下载bootstrap js包.添加此插件的引用.注意css样式要引用,不能忘记. 前台页面代码,因为楼主做的是选项卡切换查询不同的结果. <tr> &l ...
- 【洛谷P1962】斐波那契数列
斐波那契数列 题目链接:https://www.luogu.org/problemnew/show/P1962 矩阵A 1,1 1,0 用A^k即可求出feb(k). 矩阵快速幂 #include&l ...
- IBM区块链总经理谈区块链
IBM区块链总经理谈区块链:3.4年前IBM的区块链人员就达到了1500人 Captain Hiro 2018-03-20 16:22 发布在 区块链 3 18349 CCN的记者Eric Eiss ...
- EBS并发管理器启动失败,系统暂挂,在重置计数器之前修复管理程序
今天EBS安装补丁之后,因为停并发管理器的时候,因为关闭EBS应用时,并发管理器没有在前台停止,就直接停了应用服务,导致启动时,并发管理器直接起不来了,使用adcmctl.sh也没有办法启动. 进入系 ...