【专题】区间dp
1.【nyoj737】石子合并
传送门:点击打开链接
描述 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
- 输入
- 有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 - 输出
- 输出总代价的最小值,占单独的一行
- 样例输入
-
3
1 2 3
7
13 7 8 16 21 4 18 - 样例输出
-
9
239 - 思路:
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]),dp[i][j]代表从i到j合并的最小值,sum[i][j]代表从i到j的价值和。
区间dp的循环是从小区间到大区间,根据这一规律写出循环结构。
注意dp[i][i]是0。
代码:
#include<bits/stdc++.h>
using namespace std;
int dp[][],a[],sum[][];
int main()
{
int n,i,j,k;
while(cin>>n)
{
memset(sum,,sizeof(sum));
memset(dp,0x3f3f3f3f,sizeof(dp));
for(i=; i<=n; i++)
{
scanf("%d",&a[i]);
dp[i][i]=;
sum[i][i]=a[i];
}
for(i=; i<n; i++)
{
for(j=i+; j<=n; j++)
sum[i][j]+=sum[i][j-]+a[j];
}
for(int len=; len<=n; len++)
for(i=; i<=n-len+; i++)
{
j=i+len-;
for(k=i; k+<=j; k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+][j]+sum[i][j]);
}
printf("%d\n",dp[][n]);
}
return ;
}
2.【nyoj37】回文字符串
传送门:点击打开链接
给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。
样例输入
1
Ab3bd
样例输出
2
思路1:
利用反串找LCA
#include<bits/stdc++.h>
using namespace std;
char s[];
int dp[][];
int main()
{
int t,i,j;
cin>>t;
while(t--)
{
scanf("%s",s);
int n=strlen(s);
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[][]=;
for(i=; i<n; i++)
dp[i][i]=dp[i][i-]=;
for(int len=; len<=n; len++)
for(i=; i<=n-len; i++)
{
j=i+len-;
if(s[i]==s[j]) dp[i][j]=dp[i+][j-];
else dp[i][j]=min(dp[i+][j]+,dp[i][j-]+);
}
printf("%d\n",dp[][n-]);
}
}
思路2:
s[i]=s[j],dp[i][j]=dp[i+1][j-1];若!=,dp[i][j]=min(dp[i+1][j]+1,dp[i][j-1]+1)
解释一下,假如回文串是「1123」,dp[1][4] = min(dp[1][3],dp[2][4]) + 1,先把「112」看成一个整体,dp[1][3] = 1,就是说再补一个就可以回文,最后加上一个「3」,也就是 +1 操作;「123」同理。
注意dp[i][i]=0,当len=2时,若s[i]=s[j]则dp[i][j]=0,所以初始化dp[i][i-1]也要全部赋为0
#include<bits/stdc++.h>
using namespace std;
char s[];
int dp[][];
int main()
{
int t,i,j;
cin>>t;
while(t--)
{
scanf("%s",s);
int n=strlen(s);
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[][]=;
for(i=; i<n; i++)
dp[i][i]=dp[i][i-]=;
for(int len=; len<=n; len++)
for(i=; i<=n-len; i++)
{
j=i+len-;
if(s[i]==s[j]) dp[i][j]=dp[i+][j-];
else dp[i][j]=min(dp[i+][j]+,dp[i][j-]+);
}
printf("%d\n",dp[][n-]);
}
}
3.【nyoj15】括号匹配(二)
传送门:点击打开链接
描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
- 输入
- 第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100 - 输出
- 对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
- 样例输入
-
4
[]
([])[]
((]
([)] - 样例输出
-
0
0
3
2 - 思路:
- dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]),特殊情况当s[i]与s[j]匹配时,dp[i][j]=min(dp[i][j],dp[i+1][j-1])
- 注意当截取长度为2且s[i]与s[j]匹配时,不需要添加符号,所以初始化dp[i][i-1]=0,dp[i][i]=1。
#include<bits/stdc++.h>
using namespace std;
char s[];
int dp[][];
int main()
{
int t,i,j,k;
cin>>t;
while(t--)
{
scanf("%s",s);
int n=strlen(s);
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[][]=;
for(i=; i<n; i++)
{
dp[i][i]=;
dp[i][i-]=;
}
for(int len=; len<=n; len++)
for(i=; i<=n-len; i++)
{
j=i+len-;
if(s[i]=='['&&s[j]==']'||s[i]=='('&&s[j]==')')
dp[i][j]=dp[i+][j-];
for(k=i; k+<=j; k++)//这里不是else
dp[i][j]=min(dp[i][k]+dp[k+][j],dp[i][j]);
}
printf("%d\n",dp[][n-]);
}
}
4.【nyoj746】整数划分(四)
传送门:点击打开链接
给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积
- 输入
- 第一行是一个整数T,表示有T组测试数据
接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数); - 输出
- 输出每组测试样例结果为一个整数占一行
- 样例输入
-
2
111 2
1111 2 - 样例输出
-
11
121思路:
由于最大的划分所有的乘号都是固定的,可以从前到后以此找出所有乘号的位置,找出最优子结构(从结论入手向前拆分问题)。
- dp[i][j]代表0到i个数字中添加j个乘号,要求dp[n][m]即求dp[k][m-1]*a[k+1][i],应用到所有dp[i][j]=max(dp[i][j],dp[k][j-1]*a[k+1][i]),a[i][j]是从i到j的组合数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL dp[][],a[][];
char s[];
int main()
{
LL n,m,t,i,j,k;
cin>>t;
while(t--)
{
scanf("%s%lld",s,&m);
n=strlen(s);
memset(dp,,sizeof(dp));
for(i=; i<n; i++)
a[i][i]=s[i]-'';
for(i=; i<n-; i++)
for(j=i+; j<n; j++)
a[i][j]=a[i][j-]*+(s[j]-'');
for(i=; i<n; i++)
dp[i][]=a[][i];
for(j=; j<=m-; j++)
for(i=; i<n; i++)
for(k=; k+<=i; k++)
dp[i][j]=max(dp[i][j],dp[k][j-]*a[k+][i]);
printf("%lld\n",dp[n-][m-]);
}
return ;
}
【专题】区间dp的更多相关文章
- kuangbin专题十二 POJ3186 Treats for the Cows (区间dp)
Treats for the Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7949 Accepted: 42 ...
- 「kuangbin带你飞」专题二十二 区间DP
layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...
- 区间dp专题练习
区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西,\(n^2\)自己写去 \[\ \] \[\ \] 2.You Are the One 感觉自己智力被吊打 \(dp ...
- [kuangbin带你飞]专题二十二 区间DP
ID Origin Title 17 / 60 Problem A ZOJ 3537 Cake 54 / 105 Problem B LightOJ 1422 Hallowee ...
- 专题训练之区间DP
例题:以下例题部分的内容来自https://blog.csdn.net/my_sunshine26/article/details/77141398 一.石子合并问题 1.(NYOJ737)http: ...
- UESTC 2015dp专题 A 男神的礼物 区间dp
男神的礼物 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/65 Descri ...
- 区间dp专题
HDU4283You Are the One区间dp, 记忆话搜索运行时间: #include <iostream> #include <cstdio> #include ...
- P1040 加分二叉树 区间dp
题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...
- hdu 2476 区间dp
题意: 给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2 例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10 先将0~10刷一次,变成aaaaaaaaaaa 1~ ...
随机推荐
- SQL SERVER自动化运维系列
SQL SERVER自动化运维系列 转自:https://www.cnblogs.com/zhijianliutang/p/5001142.html 本系列为SQL SERVER自动化运维的一些操作技 ...
- 官方微信接口(全接口) - 微信摇一摇接口/微信多客服接口/微信支付接口/微信红包接口/微信卡券接口/微信小店接口/JSAPI
微信入口绑定,微信事件处理,微信API全部操作包含在这些文件中.微信支付.微信红包.微信卡券.微信小店. 微信开发探讨群 330393916 <?php /** * Description o ...
- PAT 天梯赛 L1-008. 求整数段和 【水】
题目链接 https://www.patest.cn/contests/gplt/L1-008 AC代码 #include <iostream> #include <cstdio&g ...
- ThreadLocal管理登录信息
通常在项目中,用户登录后,我们会将用户的信息存到session,如果想在其它地方获取session中的用户信息,我们需要先获取HttpServletRequest,再通过request.getSess ...
- Python数据处理实例
使用python进行数据处理的实例(数据为某公司HR部门关于员工信息的部分摘录,kaggle上面的一次赛题) https://www.kaggle.com/c/kfru-dbm-hr-analytic ...
- HTML5世界地图
在线演示 本地下载
- 20145219 《Java程序设计》第09周学习总结
20145219 <Java程序设计>第09周学习总结 教材学习内容总结 JDBC入门 JDBC简介 1.JDBC是java联机数据库的标准规范,它定义了一组标准类与接口,应用程序需要联机 ...
- 2018-2019-2 20165114《网络对抗技术》Exp4 恶意代码分析
Exp4 恶意代码分析 目录 一.实验目标 (1)监控你自己系统的运行状态,看有没有可疑的程序在运行. (2)分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sys ...
- iOS开发小结 - 让你的APP后台运行
最近项目有个需求需要让app在后台一直运行计时着,找了一些资料,只能用比较无耻的做法了,播放一段没有声音的音频文件,这样你的APP就不会被系统杀掉~~ 我们只需要用到<AVFoundation/ ...
- MySql判断汉字、日期、数字的具体函数
几个平常用的mysql函数,MySql判断汉字.日期.数字的具体函数分享给大家,具体内容如下 1.判断字符串是否为汉字 返回值:1-汉字 0-非汉字 ? 1 2 3 4 5 6 7 8 9 10 11 ...