区间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. 线程间操作无效: 从不是创建控件“xxxxxxxx”的线程访问它。

    方法一: Control.CheckForIllegalCrossThreadCalls = false; 方法二:(推荐) this.Invoke(new MethodInvoker(() => ...

  2. 在word文档中添加上角标和下角标

    方法一 摘录:https://jingyan.baidu.com/article/02027811b4d2da1bcc9ce5f7.html 方法二 利用MathType数学公式编辑器 exe下载:h ...

  3. STL--lower_bound()&upper_bound();

    又是两个黑科技一般的存在. 首先我们来介绍一下这两个函数: ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& ...

  4. 1-1 课程导学 & 1-2 项目需求分析,技术分解.

    1-1 课程导学 1-2 项目需求分析,技术分解. 要有一定的dart基础,了解安卓和ios的一些普通的开发

  5. 704. Binary Search

    Given a sorted (in ascending order) integer array nums of n elements and a target value, write a fun ...

  6. python __builtins__ slice类 (62)

    62.'slice', 对序列化类型数据切片,返回一个新的对象. class slice(object) | slice(stop) | slice(start, stop[, step]) | | ...

  7. Swoole和Workerman到底选谁?

    Swoole:面向生产环境的 PHP 异步网络通信引擎 使 PHP 开发人员可以编写高性能的异步并发 TCP.UDP.Unix Socket.HTTP,WebSocket 服务.Swoole 可以广泛 ...

  8. 在MacOs上安装sqlsrv Mojave - 找不到'php.h'文件

    Mojave没有安装标头. 要安装标头: open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_1 ...

  9. 多线程 线程间通信 wait,notify

    1. 方法wait锁释放,notify()锁不释放

  10. SpringBoot | contrller的使用

    @Controller 处理http请求 @RestController Spring4之后新加的注解,原来返回json需要@ResponseBody配合@Controller @RequestMap ...