hdu6049
hdu6049
题意
给出一串由 \([1, n]\) 组成的 \(n\) 个数,每个数字都不相同。现在要尽可能的分成多个块,每个块内的数可以任意排序,且分完块后可以交换两个块的位置,问使得最后序列有序可以最多分成几个块。
分析
首先暴力预处理出 \(f[i][j]\) 表示区间 \([i, j]\) 最多可以分成多少块(只有某一段区间的所有数字重排后连续才能当做一块,这个可以通过预处理出区间最大值、最小值去判断,而要想形成多个块,必须保证最小值不能改变,一定是第一个块的最小值)。( \(O(n^2)\) )
然后枚举 \([i, j]\) 也就是我们要交换的第一个块,判断合法性以及后面是否存在一个可以交换的块。( \(O(n^3)\) 其实几乎是 \(O(n^2)\) ,很多都是无效状态 )
code
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN = 3e3 + 10;
int n;
int mx[MAXN][MAXN], mn[MAXN][MAXN];
int a[MAXN], f[MAXN][MAXN]; // f[i][j] : [i, j] 最多能分成多少块
void init() {
for(int i = 1; i <= n; i++) {
mx[i][i] = mn[i][i] = a[i];
for(int j = i + 1; j <= n; j++) {
mx[i][j] = max(mx[i][j - 1], a[j]);
mn[i][j] = min(mn[i][j - 1], a[j]);
}
}
for(int i = 1; i <= n; i++) {
int cnt = 1;
f[i][i] = 1;
for(int j = i + 1; j <= n; j++) {
if(mn[i][j - 1] != mn[i][j]) cnt = 0;
if(j - i == mx[i][j] - mn[i][j]) f[i][j] = ++cnt;
}
}
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
memset(f, 0, sizeof f);
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
init();
int ans = f[1][n];
for(int i = 1; i <= n; i++) { // 枚举要交换的左端 [i, j],判断合法并寻找交换的右端
for(int j = i; j <= n; j++) {
if(f[i][j]) {
if(i == 1 || (mn[1][i - 1] == 1 && mx[1][i - 1] - mn[1][i - 1] == i - 2)) {
int x = mx[i][j];
if(x == n || (mx[x + 1][n] == n && mx[x + 1][n] - mn[x + 1][n] == n - x - 1)) {
for(int k = x; k > j; k--) {
if(f[k][x] && mn[k][x] == i) {
ans = max(ans, f[1][i - 1] + 1 + f[j + 1][k - 1] + 1 + f[x + 1][n]);
}
}
}
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
hdu6049的更多相关文章
随机推荐
- json 串转成 java 对象再拼接成前台 html 元素
获取商品参数 json 串,转成 java 对象,再拼接成前台 html 的Service方法 @Override public String getItemParam(Long itemId) { ...
- Any gotchas at all with converting from MyISAM to InnoDB?
Q: I'm ready to move from MyISAM to InnoDB but wanted to know if there was a full list of things to ...
- codevs 1078 最小生成树 kruskal
题目描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这 ...
- 第九届蓝桥杯C/C++B组题解附代码
1.标题:第几天 2000年的1月1日,是那一年的第1天.那么,2000年的5月4日,是那一年的第几天? 125天 打开日历就ok 2. 标题:明码 汉字的字形存在于字库中,即便在今天,16点阵的字库 ...
- 马上给Meltdown和Spectre漏洞打补丁
元旦之后的第一个工作日可谓是惊喜不断,4号就传来了 Google Project Zero 等团队和个人报告的 Meltdown 和 Spectre 内核漏洞的消息,首先简单介绍一下这两个内核漏洞. ...
- 精通javascript笔记(智能社)——简易tab选项卡及应用面向对象方法实现
javascript代码(常规方式/面向过程): <script type="text/javascript"> window.onload=function(){ v ...
- POJ 3070 + 51Nod 1242 大斐波那契数取余
POJ 3070 #include "iostream" #include "cstdio" using namespace std; class matrix ...
- AOP编程的常用实现方式
aop代理分为静态代理.jdk动态代理.cglib动态代理 通过动态代理的方式实现横向扩展,实现权限校验.日志等功能. jdk静态代理:代理类和委托类实现同一接口,并且在代理类中需要硬编码接口. jd ...
- HDU 4320 Arcane Numbers 1 (数论)
A - Arcane Numbers 1 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- Codeforces Round #433
我会4题,写了两题,还提交错误n次,掉了40rating(哭丧脸),又被学长D飞了. 学长:我很心疼你的成绩啊: 我:第四题忘记加特判了... 学长:暴力还能写挂. 我:...... ———————— ...