区间dp专题
HDU4283You Are the One区间dp,
记忆话搜索运行时间:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 105,inf = 1<<30;
int dp[maxn][maxn][maxn],arr[maxn],n;
int solve(int s,int e,int k){
if( s == e)return arr[s] * (k-1);
if( s > e)return 0;
if(dp[s][e][k] != inf)return dp[s][e][k]; for(int i = s; i <= e; i++){ //将区间[s,e]划分为[s,i],[i+1,e]
int nextk = k+(i-s)+1; //[i+1,e]区间内第i个人第nextk个出栈
int thisk = k+(i-s); //[s,i]区间的第s个人第thisk个出栈
int first = solve(s+1,i,k); //第1个区间经过分配得到最少屌丝值
int second = solve(i+1,e,nextk); //第2个区间经过分配得到的最少屌丝值
int cur = arr[s] * (thisk-1); //第s个人第thisk出栈增加的屌丝值
dp[s][e][k] = min(dp[s][e][k],cur+second+first);
}
return dp[s][e][k];
}
int main(){
int t,cas = 1;
scanf("%d",&t);
while( t-- ){
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",arr+i);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 0; k <= n; k++)
dp[i][j][k] = inf;
printf("Case #%d: %d\n",cas++,solve(1,n,1)); }
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn =105;
const int inf = 1<<30;
int dp[maxn][maxn],arr[maxn],sum[maxn];
int n;
int solve_dp(){
for(int len = 1; len < n; len++){ //枚举区间长度
for(int s = 1; s + len <= n; s ++){ //枚举区间起点
int end = s+len; //s为区间头,end为区间尾
for(int k = s; k <= end; k++){ //第k个出栈
int tp = arr[s] * (k-s);
tp += dp[s+1][k] + dp[k+1][end];
tp += (k-s+1) * (sum[end] - sum[k]);//重要的性质,如果第i个人第k个出栈,那么后面的人出栈顺序都大于k
dp[s][end] = min(dp[s][end],tp);
}
}
}
return dp[1][n];
}
int main(){
int t,cas = 1;
scanf("%d",&t);
while( t-- ){
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d",arr+i);
sum[i] = sum[i-1] + arr[i];
}
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
dp[i][j] = inf;
printf("Case #%d: %d\n",cas++,solve_dp());
}
return 0;
}
经典的区间DP模型--最大括号匹配数。如果找到一对匹配的括号[xxx]oooo,就把区间分成两部分,一部分是xxx,一部分是ooo,然后以此递归直到区间长度为1或者为2.
状态转移方程:if(mach(j,j+i))dp[j][j+i] = dp[j+1][j+i-1]+2;
dp[j][j+i] = max(dp[j][k],dp[k+1][j+i])(j <= k < j+i)
/*
** 一种自底向上型的DP
** 状态转移方程:if(mach(j,j+i))dp[j][j+i] = dp[j+1][j+i-1]+2;
** dp[j][j+i] = max(dp[j][k],dp[k+1][j+i])(j <= k < j+i)
*/
#include <stdio.h>
#include <cstring>
#define Max(a,b) (a)>(b)?(a):(b)
#define maxn 101
int dp[maxn][maxn];
char str[maxn];
int main()
{
while(~scanf("%s",str)) {
if(strcmp(str,"end") == 0)break;
int len = strlen(str);
memset(dp,0,sizeof(dp));
for(int i = 1; i <= len; i++) {//枚举区间长度
for(int j = 0; j <= len - i; j++) {//枚举起点
dp[j][j+i] = dp[j+1][j+i-1] ;
if((str[j] == '(' && ')'== str[j+i]) || (str[j] =='[' && str[j+i] == ']' ))
dp[j][j+i] += 2;
for(int k = j; k < i+j; k++)//枚举区间j->j+i的分界点
dp[j][j+i] = Max(dp[j][j+i],dp[j][k]+dp[k+1][j+i]);
}
}
printf("%d\n",dp[0][len-1]);
}
return 0;
}
Light OJ 1422 Halloween Costumes
很基础的区间DP,是不老传说那题的减弱版。
状态转移方程:
dp[s][e] = dp[s][e-1] (arr[s] == arr[e]).dp[s][e] = dp[s][e-1]+1 (arr[s] != arr[e]) ;
dp[s][e] = min(dp[s][e] ,dp[s][k]+dp[k+1][e]);(arr[s] == arr[k] && s <= k < e )
dp[s][e] = min(dp[s][e] ,dp[s][k]+dp[k+1][e]+1);(arr[s] != arr[k] && s <= k < e)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 110;
int dp[maxn][maxn],arr[maxn];
int main()
{
int t,cas = 1,n;
scanf("%d",&t);
while( t-- ) {
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&arr[i]);
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)dp[i][i] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n-i; j++) {
dp[j][j+i] = dp[j][j+i-1];
if(arr[j] != arr[j+i])dp[j][j+i]++;//当起点和终点不同时衣服数量加1
for(int k = j; k < j+i; k++) {
if(arr[j] == arr[k])
dp[j][j+i] = min(dp[j][j+i],dp[j][k]+dp[k+1][j+i]);//当第j和第k相等时,衣服数量等于(j->k) + (k+1->j+i)
else
dp[j][j+i] = min(dp[j][j+i],dp[j][k]+dp[k+1][j+i]+1);//当j和k不相等时,衣服数量等于(j->k) + (k+1->j+i) + 1
}
}
printf("Case %d: %d\n",cas++,dp[1][n]);
}
return 0;
}
区间dp专题的更多相关文章
- 区间dp专题练习
区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西,\(n^2\)自己写去 \[\ \] \[\ \] 2.You Are the One 感觉自己智力被吊打 \(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 ...
- [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
1.[nyoj737]石子合并 传送门:点击打开链接 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这 ...
- P1040 加分二叉树 区间dp
题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...
- dp专题训练
****************************************************************************************** 动态规划 专题训练 ...
随机推荐
- oracle的开窗函数
原创 select * from (select province, commodity, sum(price), ROW_NUMBER() OVER(PARTITION BY province o ...
- H3C模拟器实验之网络地址转换
网络拓扑图 NOTE:各个设备的基本配置在拓扑图上已经标明(需要注意的是RTB的出接口也需要配置IP,但是使用ping -a 10.1.1.1 202.117.144.1 ping不通,这点不是很理解 ...
- Windows to Linux API 映射
- 转载 | Sublime Text3 安装以及初次配置
本文引自:http://blog.csdn.net/u011272513/article/details/52088800 工具:官网下载:Sublime Text3 安装:直接运行安装.http:/ ...
- Docker 核心技术
docker是什么?为什么会出现? 容器虚拟化技术:轻量级的虚拟机(但不是虚拟机) 开发:提交代码 ——> 运维:部署 在这中间,因为环境和配置,出现问题 ——> 把代码/配置/系统/数据 ...
- cookie session sessionStorage localStorage
什么是会话? 会话指的是浏览器与服务器之间的数据交互.所白了就是 浏览器和服务器进行的请求和响应. http协议是无状态的,多次请求之间没有关联性 cookie和session的作用?干啥的? 利用c ...
- soap天气查询
public class MainActivity extends AppCompatActivity { private TextView tvContent; @Override protecte ...
- linuxdeploy安装报错
报错内容:checking installation path…fail(检查安装路径) 处理方法:安装在手机自带的存储空间中,则在路径开头加上${ENV_DIR},安装在sdcard中,加上${EX ...
- Docker入门-搭建docker私有仓库
Docker Hub 目前Docker官方维护了一个公共仓库Docker Hub,其中已经包括了数量超过15000个镜像.大部分需求都可以通过在Docker Hub中直接下载镜像来使用. 注册登录 可 ...
- linux之压缩和解压
归档:也称为打包,指的是一个文件或目录的集合,而这个集合被存储在一个文件中.归档文件没有经过压缩,因此,它占用的空间是其中所有文件和目录的总和.压缩:压缩文件也是一个文件和目录的集合,且这个集合也被存 ...