区间DP

经典石子合并问题V1    复杂度 On3

int a[SZ], sum[SZ], f[SZ][SZ];
int main()
{
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
sum[i] = sum[i-] + a[i];
}
for(int len = ; len <= n; len++)
{
for(int l = ; l <= n-len+; l++)
{
int r = l+len-;
int ans = INF;
for(int k = l; k < r; k++)
ans = min(ans, f[l][k] + f[k+][r] + sum[r] - sum[l-]);
f[l][r] = ans;
}
}
printf("%d\n", f[][n]);
return ;
}

V2 复杂度 On2

环形问题可以在后面再接一段数组

int main()
{
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
sum[i] = sum[i-] + a[i];
a[i+n] = a[i];
}
for(int i = n+; i <= *n; i++) sum[i] = sum[i-] + a[i];
for(int i = ; i <= *n; i++)
for(int j = ; j <= *n; j++)
{
if(i == j) f[i][j] = , s[i][j] = i;
else f[i][j] = INF;
}
for(int len = ; len <= n; len++)
{
for(int l = ; l <= *n-len+; l++)
{
int r = l+len-;
for(int k = s[l][r-]; k <= s[l+][r]; k++)
{
int ans = f[l][k] + f[k+][r] + sum[r] - sum[l-];
if(ans < f[l][r])
{
f[l][r] = ans;
s[l][r] = k;
}
}
}
}
int res = INF;
for(int i = ; i <= n; i++)
res = min(res, f[i][i+n-]);
printf("%d\n", res);
return ;
}

V3 复杂度 Onlogn

HDU 3516

给一堆点,在平面内选择一个位置做根,只能向右和向上连向点,问最小的连线总长度

竟然。。是区间DP问题。。。还要四边形优化

发现把两段合并好的树l~k-1  k~r 再合并在一起需要花费cal

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int SZ = ;
const int INF = 1e9+;
int a[SZ], sum[SZ], f[SZ][SZ], s[SZ][SZ];
struct node
{
int x, y;
}pos[SZ];
int cal(int l, int k, int r)
{
int ans = pos[k].x-pos[l].x + pos[k-].y-pos[r].y;
return ans;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = ; i <= n; i++) scanf("%d %d", &pos[i].x, &pos[i].y);
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
{
if(i == j) f[i][j] = , s[i][j] = i;
else f[i][j] = INF;
}
for(int len = ; len <= n; len++)
{
for(int l = ; l <= n-len+; l++)
{
int r = l+len-;
for(int k = s[l][r-]; k <= s[l+][r]; k++)
{
int ans = f[l][k-] + f[k][r] + cal(l, k, r);
if(ans <= f[l][r])
{
f[l][r] = ans;
s[l][r] = k;
}
}
}
}
printf("%d\n", f[][n]);
}
return ;
}

POJ 2955 括号匹配

为什么忘性这么大。。

int f[SZ][SZ], s[SZ][SZ];
int main()
{
char s[];
while()
{
scanf(" %s", s+);
if(s[] == 'e') break;
int n = strlen(s)-;
memset(f, , sizeof(f));
for(int len = ; len <= n; len++)
for(int l = ; l <= n-len+; l++)
{
int r = l+len-;
if((s[l] == '(' && s[r] == ')') || (s[l] == '[' && s[r] == ']')) f[l][r] = f[l+][r-]+;
for(int k = l; k < r; k++)
f[l][r] = max(f[l][r], f[l][k] + f[k+][r]);
}
printf("%d\n", f[][n]);
}
return ;
}

LightOJ 1422

题意:每一场Party都要穿相应的衣服,一次可以套着穿多件,如果某两场Party衣服一样,同一件就可以接着用,脱下过的衣服就不能再穿了 ,现在要求最少穿的衣服。

思路: f[i][j] 表示 i-j天里需要的衣服数,考虑区间dp

在l - r天内,若a[l] == a[r] 则第r天可以不穿,f[l][r] = f[l][r-1]

否则第r天要穿,f[l][r] = f[l][r-1]+1

然后枚举l - r之间的k,若a[l] == a[k] 则第k天可以不换,f[l][r] = min(f[l][r], f[l][k-1] + f[k][r])

区间DP的边界问题真的是个玄学orz

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int SZ = ;
int a[SZ], f[SZ][SZ];
int main()
{
int T, tt = ;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
memset(f, , sizeof(f));
for(int i = ; i <= n; i++) f[i][i] = ;
for(int len = ; len <= n; len++)
for(int l = ; l <= n; l++)
{
int r = l+len;
if(r > n) break;
if(a[l] == a[r]) f[l][r] = f[l][r-];
else f[l][r] = f[l][r-] + ;
for(int k = l+; k < r-; k++)
if(a[l] == a[k])
f[l][r] = min(f[l][r], f[l][k-] + f[k][r]);
}
printf("Case %d: %d\n", ++tt, f[][n]);
}
return ;
}

暑假集训 || 区间DP的更多相关文章

  1. [暑假集训--数位dp]hdu2089 不要62

    杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍, ...

  2. [暑假集训--数位dp]LightOj1205 Palindromic Numbers

    A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the sam ...

  3. [暑假集训--数位dp]hdu3709 Balanced Number

    A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. ...

  4. [暑假集训--数位dp]hdu3555 Bomb

    The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the ti ...

  5. [暑假集训--数位dp]hdu3652 B-number

    A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- ...

  6. 暑假集训 || 概率DP

    Codeforces 148D 考虑状态转移..https://www.cnblogs.com/kuangbin/archive/2012/10/04/2711184.html题意:原来袋子里有w只白 ...

  7. 暑假集训 || 树DP

    树上DP通常用到dfs https://www.cnblogs.com/mhpp/p/6628548.html POJ 2342 相邻两点不能同时被选 经典题 f[0][u]表示不选u的情况数,此时v ...

  8. 2018.8.17 2018暑假集训 关于dp的一些感想(以目前的知识水平)

    学了这么长时间的dp似乎还是不怎么样 谨以此篇文字记录一年以来与dp斗智斗勇的各种经历 关于dp(也就是动态规划)似乎对于每个OIer来说都是一个永远的噩梦. 刚刚开始学dp的时候完全搞不明白(只是觉 ...

  9. [暑假集训--数位dp]hdu5787 K-wolf Number

    Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation o ...

随机推荐

  1. #ifndef <标识> #define <标识> #endif

    头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突. 还是把 ...

  2. Eclipse安装配置Maven

    Eclipse安装配置Maven 1 安装配置Maven 1.1 下载Maven 从Apache网站 http://maven.apache.org/ 下载并且解压缩安装Apache Maven.   ...

  3. hdoj1028;他们说这题叫dp...

    #include<cstdio> #include<string> #include<iostream> #include<vector> #inclu ...

  4. python __builtins__ str类 (65)

    65.'str', 字节转换成字符串.第一个传入参数是要转换的字节,第二个参数是按什么编码转换成字符串 class str(object) | str(object='') -> str | s ...

  5. 【POJ - 2376】Cleaning Shifts(贪心)

    Cleaning Shifts Descriptions: 原文是English,我这就直接上Chinese了,想看原文的点一下链接哦 大表哥分配 N (1 <= N <= 25,000) ...

  6. 各大版本idea永久破解激活方法

    文章转载自:https://www.jiweichengzhu.com/article/a45902a1d7284c6291fe32a4a199e65c 如果还有问题,加群交流:686430774(就 ...

  7. 手机测试用例-STK测试用例

    ID 功能描述 操作步骤 预期结果 test time P/F comment tester test time P/F comment tester STK服务 SIM卡适应性测试 1.选取支持ST ...

  8. bzoj 4859 [BeiJing2017]机动训练

    题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4859 题解 和管道取珠类似 首先把平方转化成两条路径经过的图案相同的方案数 对于一条路径 方 ...

  9. A Dangerous Maze LightOJ - 1027

    这题意真是... 题意:你在一个迷宫里,有一些门,每个门有一个参数x,如果为正表明你进入门后可以花x的时间出去,如果为负表明你进入门后可以花-x的时间回到出发的地方.每次回到出发的地方之后,不能记得之 ...

  10. 线段树(区间合并) HDOJ 3308 LCIS

    题目传送门 题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence) 分析:注意是连续的子序列,就是简单的区间合 ...