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的更多相关文章

  1. kuangbin专题十二 POJ3186 Treats for the Cows (区间dp)

    Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7949   Accepted: 42 ...

  2. 「kuangbin带你飞」专题二十二 区间DP

    layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...

  3. 区间dp专题练习

    区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西,\(n^2\)自己写去 \[\ \] \[\ \] 2.You Are the One 感觉自己智力被吊打 \(dp ...

  4. [kuangbin带你飞]专题二十二 区间DP

            ID Origin Title   17 / 60 Problem A ZOJ 3537 Cake   54 / 105 Problem B LightOJ 1422 Hallowee ...

  5. 专题训练之区间DP

    例题:以下例题部分的内容来自https://blog.csdn.net/my_sunshine26/article/details/77141398 一.石子合并问题 1.(NYOJ737)http: ...

  6. UESTC 2015dp专题 A 男神的礼物 区间dp

    男神的礼物 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/65 Descri ...

  7. 区间dp专题

    HDU4283You Are the One区间dp, 记忆话搜索运行时间:   #include <iostream> #include <cstdio> #include ...

  8. P1040 加分二叉树 区间dp

    题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...

  9. hdu 2476 区间dp

    题意: 给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2 例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10 先将0~10刷一次,变成aaaaaaaaaaa 1~ ...

随机推荐

  1. servlet 文件下载

    [本文简介] 一个servlet 文件下载 的简单例子. [文件夹结构] [java代码] package com.zjm.www.servlet; import java.io.BufferedIn ...

  2. node.js基本工作原理及流程

    概述 Node.js是什么 Node 是一个服务器端 JavaScript 解释器,用于方便地搭建响应速度快.易于扩展的网络应用.Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非 ...

  3. boost noncopyable类

    1. 当声明一个类时,编译器会自动为该类生成默认构造函数,复制构造函数,赋值操作符以及析构函数: 2.自动生成的各个函数和操作符都是public的: 3.当声明一个类不允许复制时,可以将一个类的复制构 ...

  4. Maven项目settings.xml的配置

    原文地址 http://www.cnblogs.com/DreamDrive/p/5571916.html 在Maven中提供了一个settings.xml文件来定义Maven的全局环境信息.这个文件 ...

  5. Django框架之模板基础,静态文件配置

    一.模板继承 目的是:减少代码的冗余 语法: {% block classinfo %} {% endblock %} 具体步骤: 1.创建一个base.html文件,2.把要显示的页面的内容写在这里 ...

  6. 单元测试JUnit 4

    介绍   JUnit 4.x 是利用了 Java 5 的特性(Annotation)的优势,使得测试比起 3.x 版本更加的方便简单,JUnit 4.x 不是旧版本的简单升级,它是一个全新的框架,整个 ...

  7. redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表

    文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...

  8. IO 复习笔记

    输入流,从源到流中:输出流,从流到目的地. 1. 操作文件:     1).写入:FileOutputStream或者FileWriter     2).读取:FileInputStream或者Fil ...

  9. grads 新老版本目录对比

    最近不少人都在使用OpenGrADS,最新的版本已经更新到了2.0.a9,具体grads做了哪些更新,在附件里面放了一个,是英文的. 很多人说在使用原来的一些教程的时候找不到相对应的文件夹了,其实仔细 ...

  10. Entity FrameWork Code First无法生成数据库 解决办法

    我是控制台应用程序,没有connectionStrings,试了几个方法也都不可以. 这是别人的博客用其他方法. http://www.cnblogs.com/Gyoung/archive/2013/ ...