题目链接

对于基本区间dp,设dp[l][r]是区间l到r的最大价值。

我们可以枚举区间的长度,在枚举左端点,判断即可。

当右端点大于n,就break。

dp[l][r]=max(dp[l+1][r]+v[l]*(n-i+1),dp[l][r-1]+v[r]*(n-i+1))

别忘了初始化,dp[i][i]=n*v[i].

代码:

 1 #include<cstdio>
2 #include<iostream>
3 using namespace std;
4 int dp[3000][3000];
5 int n,v[3000];
6 int main(){
7 scanf("%d",&n);
8 for(int i=1;i<=n;++i)
9 scanf("%d",&v[i]);
10 for(int i=1;i<=n;++i)dp[i][i]=n*v[i];
11 for(int i=2;i<=n;++i){
12 for(int l=1;l<=n;l++){
13 int r=l+i-1;
14 if(r>n)break;
15 dp[l][r]=max(dp[l+1][r]+v[l]*(n-i+1),dp[l][r-1]+v[r]*(n-i+1));
16 }
17 }printf("%d\n",dp[1][n]);
18 return 0;
19 }

题目链接

也可以用区间dp做。

设dp[i][j]是区间[i,j]的最佳答案。

我们枚举区间。

对于每次区间,枚举合并的交点。

当且仅当合并两方值相等时才能合并。

if(dp[i][k]==dp[k+1][j])dp[i][j]=max(dp[i][j],dp[i][k]+1)

代码:

#include<cstdio>
#include<iostream>
using namespace std;
int n,dp[500][500],ans=-(1<<30);
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&dp[i][i]);
for(int i=n-1;i>=1;--i){
for(int j=i+1;j<=n;++j){
for(int k=i;k<j;++k)
if(dp[i][k]==dp[k+1][j])//可以合并
dp[i][j]=max(dp[i][j],dp[i][k]+1);//dp[i][k]&dp[k+1][j]'s merge
ans=max(ans,dp[i][j]);//max
}
}printf("%d\n",ans);
return 0;
}

题目链接

本题与上一题类似,发现样例都一样。

但是神奇的数据范围不得不让我们重新考虑转移方程。

一看每个数都小于等于40,那么很容易想到dp中的一维表示合并的数。

看题解后恍然大悟,设dp[i][j]是能够合并成i且左端点为j的右端点的位置。

那么,dp[i][j]=dp[i-1][dp[i-1][j]]

即,当一个数可以合并成i时,一定是由i-1合并出来的。

我们画一个数轴,其中j在左边。

那么,能合并出i-1的位置就在dp[i-1][j]

那么继续往后,在合并出一个i-1,那么这个位置显然是:

dp[i-1][dp[i-1][j]]

至此,得到转移方程。

那么,表示数字时,我们只需要开到58.

首先,因为数字小于等于40.其次,

262144=218.

用类似倍增的思想,来倍增2.

于是我们要开到58.(也可以用运气法开个大的)

代码:

 1 #include<cstdio>
2 #include<iostream>
3 #define MAXN 262144+100
4 using namespace std;
5 int n,a[MAXN],ans;
6 int dp[59][MAXN];
7 int main(){
8 scanf("%d",&n);
9 for(int i=1;i<=n;++i)scanf("%d",&a[i]),dp[a[i]][i]=i+1;
10 for(int i=2;i<=58;i++){
11 for(int j=1;j<=n;j++){
12 if(!dp[i][j])dp[i][j]=dp[i-1][dp[i-1][j]];
13 if(dp[i][j])ans=max(ans,i);
14 }
15 }printf("%d\n",ans);
16 return 0;
17 }

题目链接

我们可以先断环为链,然后枚举右端点。相应的,左端点从右端点依次枚举到1.

那么,设dp[i][j]是区间【i,j】合并的最优策略,则有:

dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1])

我们在i与j之间枚举k做断点,后面部分就是新合并后的价值。

代码:

#include<cstdio>
#include<iostream>
using namespace std;
struct node{
int l,r;//l from r to
}q[300];
int n,a[300],maxn;
int dp[300][300];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]),a[i+n]=a[i];
for(int j=2;j<=(n<<1);++j){//枚举右端点
for(int i=j-1;j-i<n&&i>=1;i--){//向左依次枚举区间
for(int k=i;k<j;++k){//枚举断点
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1]);
maxn=max(dp[i][j],maxn);//每次合并=max(左区间值+右区间值+新合并的值)
}//取max
}
}
printf("%d\n",maxn);
return 0;
}

简单区间dp的更多相关文章

  1. 简单Dp----最长公共子序列,DAG最长路,简单区间DP等

    /* uva 111 * 题意: * 顺序有变化的最长公共子序列: * 模板: */ #include<iostream> #include<cstdio> #include& ...

  2. poj1651 Multiplication Puzzle(简单区间dp)

    题目链接:http://poj.org/problem?id=1651 题意:一系列的数字,除了头尾不能动,每次取出一个数字,这个数字与左右相邻数字的乘积为其价值, 最后将所有价值加起来,要求最小值. ...

  3. 租用游艇(简单区间dp)

    租用游艇 时间限制: 1 Sec  内存限制: 128 MB提交: 1  解决: 1[提交][状态][讨论版][命题人:quanxing] 题目描述 长江游艇俱乐部在长江上设置了n 个游艇出租站1,2 ...

  4. [luogu2446][bzoj2037][SDOI2008]Sue的小球【区间DP】

    分析 简单区间DP, 定义状态f[i][j][0/1]为取完i-j的小球最后取i/j上的小球所能获得的最大价值. 排序转移. ac代码 #include <bits/stdc++.h> # ...

  5. POJ2955--Brackets 区间DP入门 括号匹配

    题意很简单,就是求给出串中最大的括号匹配数目.基础题,格式基本为简单区间dp模板. #include<iostream> #include<string.h> using na ...

  6. Codeforces Round #336 (Div. 2)B 暴力 C dp D 区间dp

    B. Hamming Distance Sum time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. [THUSC2016]成绩单 [区间dp]

    简单区间dp. 考虑 \(f_{i,j,mn,mx}\)表示 \(i,j\) 区间的最大值为 \(mx\),最小值为 \(mn\) 的最小花费,\(g_{i,j}\) 为删掉 \([i,j]\) 的最 ...

  8. tyvj 1198 矩阵连乘——区间dp

    tyvj 1198 矩阵连乘 题目描述 一个n*m矩阵由n行m列共n*m个数排列而成.两个矩阵A和B可以相乘当且仅当A的列数等于B的行数.一个N*M的矩阵乘以一个M*P的矩阵等于一个N*P的矩阵,运算 ...

  9. 区间dp复习 之 tyvj 1198 矩阵连乘

    题目描述 一个\(n*m\)矩阵由\(n\)行\(m\)列共\(n*m\)个数排列而成.两个矩阵\(A\)和\(B\)可以相乘当且仅当\(A\)的列数等于\(B\)的行数.一个\(N*M\)的矩阵乘以 ...

随机推荐

  1. css学习入门-第一个css程序

    1.css的优势: --内容与表现分离 --网页结构统一,可以实现复用 --样式丰富 2.css的3种导入方式 2.1行内样式 <h1 style="color: red"& ...

  2. Unity报与System.IO相关的错误

    比如这个: Type `System.IO.FileInfo' does not contain a definition for `OpenText' and no extension method ...

  3. unity 4种实现动态障碍方法

    此文将介绍4种实现动态障碍的方法,2种基于navmesh,2种基于astar算法. 1.基于navmesh. 1.制作场景障碍: a.有几个独立的障碍物,就定义几个user area,即,一个场景仅仅 ...

  4. HDU - 4548-美素数 (欧拉素数筛+打表)

    小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识.  问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为"美素数&quo ...

  5. [BUUOJ记录] [BJDCTF 2nd]fake google

    本题考查python jinjia2的ssti,其实tplmap直接梭哈都可以 随便输入一个值,查看源代码就能看到一个Hint: 用下面的流程图测试一下,看看是什么模板引擎: 用Payload测试之后 ...

  6. SpringMVC实例及注解(二)

    @RequestMapping()除了修饰方法,还可以修饰类1.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录2.方法处:提供进一步的细分映射信息.相对于类定义处的URL.若类定义处未标注 ...

  7. 大厂运维必备技能:PB级数据仓库性能调优

    摘要:众所周知,数据量大了之后,性能是大家关注的一点,所以我们在业务开发的时候,特别关注性能,做为一个架构师,必须对性能要了解,要懂.才能设计出高性能的业务系统. 一.GaussDB分布式架构 所谓集 ...

  8. Java网络通信 —— 序列化问题

    Java序列化的目的主要有两个: 1.网络传输 2.对象持久化 当选行远程跨迸程服务调用时,需要把被传输的Java对象编码为字节数组或者ByteBuffer对象.而当远程服务读取到ByteBuffer ...

  9. vue父子组件状态同步的最佳方式

    哈喽!大家好!我是木瓜太香,一位老牌儿前端工程师,平时我们在使用 vue 开发的时候,可能会遇到需要父组件与子组件某个状态需要同步的情况,通常这个是因为我们封装组件的时候有一个相同的状态外面要用,里面 ...

  10. 为什么ping不通google.com

    前言 为什么在ping不通Google的时候,我们却可以web直接访问Google (已开启SSR 翻 墙) SSR访问Google 因为GFW的限制导致国内无法直接访问谷歌,那么SSR为什么能绕过限 ...