暑假集训 || 区间DP
区间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的更多相关文章
- [暑假集训--数位dp]hdu2089 不要62
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍, ...
- [暑假集训--数位dp]LightOj1205 Palindromic Numbers
A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the sam ...
- [暑假集训--数位dp]hdu3709 Balanced Number
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. ...
- [暑假集训--数位dp]hdu3555 Bomb
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the ti ...
- [暑假集训--数位dp]hdu3652 B-number
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- ...
- 暑假集训 || 概率DP
Codeforces 148D 考虑状态转移..https://www.cnblogs.com/kuangbin/archive/2012/10/04/2711184.html题意:原来袋子里有w只白 ...
- 暑假集训 || 树DP
树上DP通常用到dfs https://www.cnblogs.com/mhpp/p/6628548.html POJ 2342 相邻两点不能同时被选 经典题 f[0][u]表示不选u的情况数,此时v ...
- 2018.8.17 2018暑假集训 关于dp的一些感想(以目前的知识水平)
学了这么长时间的dp似乎还是不怎么样 谨以此篇文字记录一年以来与dp斗智斗勇的各种经历 关于dp(也就是动态规划)似乎对于每个OIer来说都是一个永远的噩梦. 刚刚开始学dp的时候完全搞不明白(只是觉 ...
- [暑假集训--数位dp]hdu5787 K-wolf Number
Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation o ...
随机推荐
- git只clone仓库中指定子目录
基于sparse clone变通方法 [root@vm_test backup]# mkdir devops[root@vm_test backup]# cd devops/[root@vm_test ...
- C# 利用Aspose.Slides.dll将本地ppt文档转化成pdf(完美破解版 无水印 无中文乱码)
下载Aspose.Slides.dll http://pan.baidu.com/s/1kVPjnzL 添加引用C#代码. using System; using System.Collectio ...
- Java泛型简明教程
泛型是Java SE 5.0中引入的一项特征,自从这项语言特征出现多年来,我相信,几乎所有的Java程序员不仅听说过,而且使用过它.关于Java泛型的教程,免费的,不免费的,有很多.我遇到的最好的教材 ...
- 数据连接池使用方法 JADI
1.编写context.xml 文件复制到 WebRoot/META_INF/context.xml <?xml version='1.0' encoding='utf-8'?> < ...
- Unity网格合并_材质合并[转]
http://blog.csdn.net/chenggong2dm/article/details/41699029
- zoj2412 dfs连通图
zoj2412 #include<stdio.h> #include<iostream> #include<cstdio> #include<queue> ...
- python __builtins__ tuple类 (68)
68.'tuple', 转换为元组类型 class tuple(object) | tuple() -> empty tuple | tuple(iterable) -> tuple in ...
- 解决 Xshell 连接出现 The remote SSH server rejected X11 forwarding request 问题
问题描述 使用 Xshell 5 首次连接虚拟机 CentOS 7.6 出现这样的提示: WARNING! The remote SSH server rejected X11 forwarding ...
- LuoguP2055 [ZJOI2009]假期的宿舍【二分图最大匹配】By cellur925
题目传送门 这道题开始感觉不出是二分图最大匹配的qwq.但是今天学了匈牙利算法,想来做几个题qwq.做这个题的时候想了很久它哪里是二分图,脑子里是“两列,每列有很多点的那种图 qwq.” 然后看了题解 ...
- pyrcharm 编程规范
正常变量赋值, 等号左右各一个空格: 参数赋值, 等号左右都没有空格: 注释#后面一个空格 类定义和函数定义,前后各两行,而在类的里面定义成员函数,只需要空一行 文件最后一个空行 变量.函数.类最好都 ...