区间DP,是一类具有较为固定解法的DP,一般的思路都是:

first.初始化区间长度为1的情况(一般区间长度为1的较易于初始化)

second.

for(枚举区间长度2~n){
for(枚举左端点){
j=i+len-//记录右端点
for(枚举断点){
//枚举断点后一般是比较以哪个断点分开最优(一般是比较最大或最小)
}
}
}

end.区间DP的特点:

合并:即将两个或多个部分进行整合,当然也可以反过来,也就是对一个问题分解成两个或多个部分。

特征:能将问题分解为两两合并的形式;

求解:对整个问题设最优值,枚举合并点,将问题分解成左右两部分,最后合并左右两个部分的最优值得到原问题的最优值。(显然无后效性啦)

然后我发现区间DP的数据范围都超级小,100左右


下面我萌以石子合并为例子来看具体的看区间DP:

石子合并【题目链接】

首先要说的是:这道题贪心是不对哒;

然后看正解:区间DP

如果第i堆石子与第j堆石子合并成一堆,说明i~j之间的所有石子也都被合并成了一堆,然后对于合并第i堆石子与第j堆石子的代价,可以看做是先将第i~k堆石子合并,再将第k+1~j堆石子合并的代价别忘记再加上Σ(k=i~j)val[k](val[i]表示第i堆石子的个数,显然不管你合并啥,只要合并第i堆石子~第j堆石子,一定需要加上第i堆石子到第j堆石子的和(感性理解一下qwq)),然后需要求最优的话,就是枚举i~j之间每一个断点k,取最优。

定义:sum[i]表示Σ(k=1~i)val[k](运用了前缀和的思想,如果要求区间i~j的和,可以用sum[j]-sum[i-1])

f_min[i][j]表示合并区间i~j所需要的最小花费;

f_max[i][j]表示合并区间i~j所需要的最大花费;

初始条件:f_min[i][i]=f_max[i][i]=0;(只合并自己一堆显然需要花费为0)

转移方程:

f_min[i][j]=min(f_min[i][j],f_min[i][k]+f_min[k+1][j])+sum[j]-sum[i-1];

f_max[i][j]=max(f_max[i][j],f_max[i][k]+f_max[k+1][j])+sum[j]-sum[i-1];

(i<=k<=j)

显然这个题需要枚举区间长度一层for,枚举区间起点一层for,枚举断点k一层for,然后就是三层for,时间复杂度O(n^3);


然后是对于环的处理,最好写好用的处理方法,把序列延长为原来的两倍。然后最后枚举一下取最优值就好了。

CODE:

#include<bits/stdc++.h>
#define ll long long
#define INF 2147483647 using namespace std; inline int read(){
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} int n,val[];
int f_max[][],f_min[][],sum[]; int main(){
n=read();
for(int i=;i<=n;i++)
val[i]=read(),val[i+n]=val[i];
memset(f_min,0x3f,sizeof(f_min));
for(int i=;i<=*n;i++){
sum[i]=sum[i-]+val[i];
f_min[i][i]=;f_max[i][i]=;
}
for(int len=;len<=n;len++){
for(int i=;i+len-<=*n;i++){
int j=i+len-;
for(int k=i;k<=j;k++){
f_min[i][j]=min(f_min[i][j],f_min[i][k]+f_min[k+][j]);
f_max[i][j]=max(f_max[i][j],f_max[i][k]+f_max[k+][j]);
}
f_min[i][j]+=(sum[j]-sum[i-]);
f_max[i][j]+=(sum[j]-sum[i-]);
}
}
int ans_min=INF,ans_max=;
for(int i=;i<=n;i++){
ans_min=min(ans_min,f_min[i][i+n-]);
ans_max=max(ans_max,f_max[i][i+n-]);
}
cout<<ans_min<<endl<<ans_max<<endl;
return ;
}

跑去做题(逃

end-

以石子合并为例的区间DP的更多相关文章

  1. NYOJ 石子合并(一) 区间dp入门级别

    描述    有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价 ...

  2. CSU 1592 石子合并 (经典题)【区间DP】

    <题目链接> 题目大意: 现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input ...

  3. NYOJ 石子合并(一)(区间DP)

    题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 题目大意: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆 ...

  4. 石子合并/能量项链【区间dp】

    题目链接:http://www.51mxd.cn/problem.php-pid=737.htm 题目大意:给出n个石子堆以及这n个石子堆中石子数目,每次操作合并两个相邻的石子堆,代价为两个石子堆数目 ...

  5. nyoj737 石子合并(一) 区间DP

    dp[x][y]表示合并[x, y]区间的石子的最小花费,将区间长度递增枚举即可. AC代码: #include<cstdio> #include<algorithm> usi ...

  6. 石子合并(四边形不等式优化dp) POJ1160

    该来的总是要来的———————— 经典问题,石子合并. 对于 f[i][j]= min{f[i][k]+f[k+1][j]+w[i][j]} From 黑书 凸四边形不等式:w[a][c]+w[b][ ...

  7. 【整理】石子合并问题(四边形不等式DP优化)

    有很多种算法: 1,任意两堆可以合并:贪心+单调队列. 2,相邻两堆可合并:区间DP    (O(n^3)) ). 3,相邻,四边形不等式优化DP (O(n^2) ). 4,相邻,GarsiaWach ...

  8. 【BZOJ1413】取石子游戏(博弈,区间DP)

    题意:在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中 ...

  9. 51 nod 石子归并 + v2 + v3(区间dp,区间dp+平行四边形优化,GarsiaWachs算法)

    题意:就是求石子归并. 题解:当范围在100左右是可以之间简单的区间dp,如果范围在1000左右就要考虑用平行四边形优化. 就是多加一个p[i][j]表示在i到j内的取最优解的位置k,注意能使用平行四 ...

随机推荐

  1. Cortex-M3 入门指南(三):时钟总线与复位时钟控制器

    [reset clock control  复位和时钟控制器] 时钟信号对于处理器非常重要,比如我们熟悉的 CPU 就是由时钟信号驱动的,而主频就是内核的的时钟信号频率.Cortex-M3 有着复杂的 ...

  2. Codeforces 785 D.Anton and School - 2(组合数处理)

    Codeforces 785 D.Anton and School - 2 题目大意:从一串由"(",")"组成的字符串中,找出有多少个子序列满足:序列长度为偶 ...

  3. Linux Ubuntu 用c++11编译

    加上: -std=c++ 例如: g++ test.

  4. TCP之11种状态变迁

    1. TCP 之11种状态变迁 TCP 为一个连接定义了 11 种状态,并且 TCP 规则规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态.如,当某个应用进程在 CLOSED 状 ...

  5. State Threads之网络架构库

    原文: State Threads for Internet Applications 介绍 State Threads is an application library which provide ...

  6. LC 553. Optimal Division

    Given a list of positive integers, the adjacent integers will perform the float division. For exampl ...

  7. 热门搜索词获取java版

    日常生活中经常会有这样的需求,就是网站上.app上需要展示近期热搜的一些词汇,其实常用的做法当然是自己写爬虫去爬,不过这种办法是在太麻烦了,为了节省时间,可以调用一些接口来实现,比如常用的聚合数据,小 ...

  8. TCP/IP及内核参数优化调优(转)

    Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等.如下配置是写在sysctl.conf ...

  9. 程序员查问题还是要找stackoverflow

    今天定位了一个问题,其实也不是多复杂. 现场的数据是postgres dump出来的,想拿到本地服务器restore后定位问题. 本地restore后报错,报sequence as data_type ...

  10. java浮点型数据保留两位小数

    /*** * 保留2位小数 * @param floatValue * @return */ float scale(Float floatValue) { DecimalFormat format ...