区间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. 010-- 开发脚本自动部署nginx_web和nfs及监控内存

    1.编写脚本自动部署反向代理.web.nfs: #!/bin/bash #检测安装nginx function detection_nginx(){ if [ -f /etc/nginx/nginx. ...

  2. 51nod 1003【数学】

    思路: 2和5能构成0,然后就是看2和5因子组成个数,然而我们知道,1-n中2的因子数肯定>5的,所以我们只要求一下1-n中5的因子个数就好了... #include <stdio.h&g ...

  3. POJ2369【循环节】

    题意: 给一个序列,他需要几步就能变成原来的序列. 思路: 那么就是找一下各个循环节(用dfs随便搞了-),求一下最小公倍数就好了. 贴一发挫code- //#include <bits/std ...

  4. SpringBoot自定义参数解析器

    一.背景 平常经常用 @RequestParam注解来获取参数,然后想到我能不能写个自己注解获取请求的ip地址呢?就像这样 @IP String ip 二.分析 于是开始分析 @RequestPara ...

  5. Codeforces 1144F(二分染色)

    发现奇环不可行,偶环可行,考虑二分图.然后染色,方向全都从一种指向另一种就可以了,随意. ; int n, m, color[maxn]; vector<int> vc[maxn]; ve ...

  6. AtCoder Grand Contest 012 A

    A - AtCoder Group Contest Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statem ...

  7. Query on a tree again! SPOJ - QTREE3

    https://vjudge.net/problem/SPOJ-QTREE3 https://www.luogu.org/problemnew/show/P4116 一个log(LCT)比两个log( ...

  8. 洛谷 P4585 [FJOI2015]火星商店问题

    (勿看,仅作笔记) bzoj权限题... https://www.luogu.org/problemnew/show/P4585 对于特殊商品,直接可持久化trie处理一下即可 剩下的,想了一段时间c ...

  9. git部分指令

    git stash #会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录 git stach pop #恢复之前缓存的工作目录 切换分支: git checkout de ...

  10. JAVA常用知识总结(一)

    try catch finally 的详细用法: public static int testBasic(){ int i = 1; try{ i++; System.out.println(&quo ...