区间DP 基本题集
51 Nod 1021 石子归并
模板题,敲就完事了,注意一下这种状态转移方程有个四边形的优化(时间)
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std; int n;
const int maxn=1e3+;
int f[maxn][maxn], s[maxn][maxn], a[maxn], sum[maxn]; void solve_sim()
{
memset(f, 0x3f, sizeof(f));
for(int i=; i<=n; i++)
f[i][i]=; for(int len=; len<n; len++)
for(int i=; i<=n-len; i++)
{
int j=i+len;
for(int k=i; k<j; k++)
f[i][j]=min(f[i][j], f[i][k]+f[k+][j]+sum[j]-sum[i-]);
}
} void solve_opt()
{
memset(f, 0x3f, sizeof(f));
for(int i=; i<=n; i++){
f[i][i]=; s[i][i]=i;
} for(int len=; len<n; len++)
for(int i=; i<=n-len; i++)
{
int j=i+len;
for(int k=s[i][j-]; k<=s[i+][j]; k++)
{
if(f[i][j]>f[i][k]+f[k+][j])
{
f[i][j]=f[i][k]+f[k+][j];
s[i][j]=k;
}
}
f[i][j]+=sum[j]-sum[i-];
}
} int main()
{
cin>>n;
for(int i=; i<=n; i++)
{
cin>>a[i];
sum[i]=sum[i-]+a[i];
} solve_sim();
solve_opt(); cout<<f[][n]<<endl;
return ;
}
POJ 3186 喂牛
题意:给你n个数字.....每次你可以取出最左端的数字或者取出最右端的数字,一共取n次取完。假设你第i次取的数字是x,你可以获得i*x的价值。求总价值之和最大。
题解:区间DP问题,子问题:在dp[i][j]这段区间所获得的最大价值;
划分:取左边或者取右边,这个是从底往上推的,初始化要注意,
方程:f[i][j]=max(f[i+1][j]+(n-len)*a[i], f[i][j-1]+(n-len)*a[j])
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int INF=0x3f3f3f3f;
const int maxn=2e3+;
int f[maxn][maxn], a[maxn]; int main()
{
//freopen("in.txt", "r", stdin);
int n; cin>>n;
for(int i=; i<=n; i++){
cin>>a[i];
f[i][i]=a[i]*n;
}
for(int len=; len<n; len++)
for(int i=; i<=n-len; i++){
int j=i+len;
f[i][j]=max(f[i+][j]+(n-len)*a[i], f[i][j-]+(n-len)*a[j]);
}
cout<<f[][n]<<endl;
return ;
}
POJ 2955 括号匹配
题意:给一串字符,求可以匹配的括号个数,有(), [],这2种括号
题解:区间DP问题,子问题:在区间i,j上的最大可匹配的括号数目;
划分:首尾匹配, 首尾不匹配,当首尾不匹配的时候必然可以由2段区间合并来(想一下),枚举所有的子区间组合(分割点);
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std; const int maxn=;
char s[maxn];
int f[maxn][maxn]; int main()
{
while(scanf("%s",s+), s[]!='e')
{
memset(f, , sizeof(f));
int n=strlen(s+);
for(int len=; len<n; len++)
for(int i=; i<=n-len; i++) //注意这个i是可以等于n-len
{
int j=i+len;
if(s[i]=='('&&s[j]==')' || s[i]=='['&&s[j]==']')
f[i][j]=f[i+][j-]+; //不是由拼接得来的
for(int k=i; k<j; k++)
f[i][j]=max(f[i][j], f[i][k]+f[k+][j]);//由拼接得来的
}
printf("%d\n", f[][n]);
}
return ;
}
POJ 3280 求变成回文串的代价
题意:给定一个字符串S,字符串S的长度为M,字符串S所含有的字符的种类的数量为N(最多26种 小写字母),然后给定这N种字符Add与Delete的代价,求将S变为回文串的最小代价和。
题解:区间DP,子问题:当i,j的区间是回文串的时候所要付出的代价;
划分:首尾相等,直接转, 首尾不等,长区间是由比它短一的区间延展来的,从左边还是右边
注意:这个初始化,我是真的有点问题,找for循环下的状态转移的临界条件,如果不行的话,在for循环下初始化;
这个给出2个cost,删除和添加其实只要选其中较小的一个即可;
总结:此题在写的时候,思路就错了,这个区间dp问题,它的问题不是由2段短的区间和并来的, 而是由短区间往2边扩展来的,直到扩展到1-n;
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string >
using namespace std; const int maxm=2e3+;
const int INF=0x3f3f3f3f;
int cost[], f[maxm][maxm];
char s[maxm]; int main()
{
//freopen("in.txt", "r", stdin);
int k,n; cin>>k>>n;
scanf("%s", s+);
while(k--)
{
char data; cin>>data;
int ac,dc; cin>>ac>>dc;
cost[data-'a']=min(ac, dc);
} /*
memset(f, 0x3f, sizeof(f));
for(int i=0; i<=n; i++) f[i][i]=0; ///这个初始化是不对的,找了我好久
*/ for(int len=; len<n; len++)
for(int i=; i<=n-len; i++)
{
int j=i+len;
f[i][j]=INF;
if(s[i]==s[j])
f[i][j]=f[i+][j-];
else
{
f[i][j]=min(f[i][j], f[i+][j]+cost[s[i]-'a']);
f[i][j]=min(f[i][j], f[i][j-]+cost[s[j]-'a']);
}
}
cout<<f[][n]<<endl;
return ;
}
区间DP 基本题集的更多相关文章
- 【省选十连测之九】【DP】【组合计数去重】【欧拉函数】基本题
目录 题意: 输入格式: 输出格式: 数据范围: 思路: 嵌套题的转移 基本题的转移 Part1 Part2 Part3 代码 题意: 这是一个关于括号组合的题. 首先定义一道题是由'(',')',' ...
- 区间DP入门题目合集
区间DP主要思想是先在小区间取得最优解,然后小区间合并时更新大区间的最优解. 基本代码: //mst(dp,0) 初始化DP数组 ;i<=n;i++) { dp[i][i]=初始 ...
- HDU 4283---You Are the One(区间DP)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4283 Problem Description The TV shows such as Y ...
- 合并傻子//区间dp
P1062 合并傻子 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 从前有一堆傻子,钟某人要合并他们~但是,合并傻子是要掉RP的...... 描述 在一个园 ...
- POJ 3280 Cheapest Palindrome (区间DP) 经典
<题目链接> 题目大意: 一个由小写字母组成的字符串,给出字符的种类,以及字符串的长度,再给出添加每个字符和删除每个字符的代价,问你要使这个字符串变成回文串的最小代价. 解题分析: 一道区 ...
- 区间dp之四边形不等式优化详解及证明
看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...
- 【区间DP】【lgP3146】248
传送门 Description 给定一个1*n的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少.注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3. In ...
- UVA 1626 区间dp、打印路径
uva 紫书例题,这个区间dp最容易错的应该是(S)这种匹配情况,如果不是题目中给了提示我就忽略了,只想着左右分割忘记了这种特殊的例子. dp[i][j]=MIN{dp[i+1][j-1] | if( ...
- 能量项链 (区间DP)
能量项链 (区间DP) 问题引入 能量项链 洛谷 P1063 思路 诸如此类不能线性规划的问题要用到区间DP,区间DP一般就是三层循环,第一层表示区间长度(本题即\(n\)),第二层枚举起点并根据第一 ...
随机推荐
- Oracle 11g R2 Backup Data Pump(数据泵)之expdp/impdp工具
Oracle Data Pump(以下简称数据泵)是Oracle 10g开始提供的一种数据迁移工具,同时也被广大DBA用来作为数据库的逻辑备份工具和体量较小的数据迁移工具.与传统的数据导出/导入工具, ...
- SQL Server get SP parameters and get output fields type information
Summary 本文主要介绍一下,SQL里面的两个很实用的两个操作: 获取存储过程的参数信息 SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPE ...
- c#子类序列化与父类序列化(Serializable)的区别
今天码代码,遇到了一个很奇怪的问题.就是子类继承了Serializable,父类没有,最后面,子类的数据转为byte[],并存储到数据库,再从数据库出来转为子类对象,发现,父类的变量,值为空! 最后调 ...
- vue路由请求 router
创建一个Router.js文件 // 路由请求//声明一个常量设置路菜单// import Vue from "vue/types/index";import Vue from ' ...
- Spring Boot:简介
一.概述 Spring Boot 是Java一个开源框架,主要用途是用来创建微服务:可以用来创建独立的.生产的基于Spring的应用程序. Spring Boot 采用默认配置观点,多数Spring ...
- Python练习:含参数的脚本示例
首先准备一个example.csv文件,如下: 编写脚本test.py ,实现传入参数,读取example.csv文件,并将其保存为另一个文件, # 含参数的脚本,读取一个文件,并另保存一个文件im ...
- CentOS7中PPTP的配置
最近做各种vpn,记录一下pptp的流程 1.准备 #yum install -y perl ppp iptables //centos默认安装了iptables和ppp 2.安装pptpd #y ...
- 网络库压力测试:mongols VS evpp
evpp是360出品的一个网络库,基于libevent,进行了许多改造,对c++11友好.据称比libevent性能要好. 到底有多好呢?360开发人员有自己的测试,信不信由你. evpp源码下有个h ...
- final关键字的几种用法
在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们来了解一下final ...
- pgrep
优势:可以只显示进程号 pgrep -l 显示进程名