区间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\)),第二层枚举起点并根据第一 ...
随机推荐
- 关于表情的战争APP隐私政策网址
本软件尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本软件会按照本隐私权政策的规定使用和披露您的个人信息.但本软件将以高度的勤勉.审慎义务对待这些信息.除本隐私权政策另 ...
- HDU 1556 BIT区间修改+单点查询(fread读入优化)
BIT区间修改+单点查询 [题目链接]BIT区间修改+单点查询 &题解: BIT区间修改+单点查询和求和的bit是一模一样的(包括add,sum) 只不过是你使用函数的方式不一样: 使用区间的 ...
- https----------如何在phpstudy环境下配置apache的https访问以及访问http自动跳转成https
1.首先在 httpd.conf里面修改几个地方 找到 #LoadModule ssl_module modules/mod_ssl.so 去掉前面的# Include conf/vhosts.con ...
- nginx+fastCGI
首先贴些遇到的问题,之后再整理 1.yum -y install pcre zlib OpenSSL openssl-devel pcre-devel 2. nginx: [emerg] " ...
- centos7 安装oracle 11g数据库
1.新建oracle用户 groupadd oracle useradd -g oracle oracle .修改操作系统核心参数 在Root用户下执行以下步骤: 1)修改用户的SHELL的限制,修改 ...
- 解决多版本共存时,python/pip等命令失效
问题呈现: Windows环境下,多版本Python解释器共存时,由于未配置环境变量或者反复卸载重装解释器等原因,CMD交互下输入Python或者pip等命令时失效 解决方式: 1)配置各个解释器的环 ...
- Java stream的常见用法
不讲原理,只说用法. 1,集合遍历 public class StreamTest { public static void main(String[] args) { //1 遍历 List< ...
- VC6中函数点go to definition报告the symbol XXX is undefined
删除Debug中的bsc文件,再重建所有文件即可,在该函数处点击go to definition会提示重建.bsc文件,如果不行,多操作几次.
- WEB学习小笔记
环境基于WIN10.IDEA最新版.JDK1.8.TOMCAT9 下面说的有错的地方希望指出,谢谢. STRUT2 1.在maven下的时候系统会系统创建一个叫做log4j的配置文件,但是到了这个版本 ...
- cnetos7设置中文显示及中文输入法
Centos7安装的时候即使选择了中文安装,因为安装后并没有GUI,即使后来安装GUI后默认依旧是英文显示. 输入locale后显示的是 永久修改成中文:编辑/etc/profile.d/lang.s ...