好久没写博客了呀,今天写一个。才不是因为今天发博客可以得一个勋章
题目链接:http://codeforces.com/gym/101911/problem/K
题目大意:给一个长度为n的数组和一个整数m,让你往中间插板子,问你最多有多少个子区间满足排完序后中位数大于等于m(序列长度为偶数的话去中间两个较小的一个)。
解题思路:最开始想着划分树什么的,看了看别人的题解,用dp可以求解。
===写作业去了,思路待会再写
update:
用一个数组vis[i][j]标记区间[i, j]是符合条件的区间,dp[i]表示以i为结尾的区间中,最多能分成的区间个数
那么dp[n]就是答案了
考虑dp细节:
其实很显然了。。对于每一个右端点,枚举每一个左端点,dp[i] = max(dp[i], dp[j] + 1);
这样时间复杂度O(n ^ 2)
#pragma GCC diagnostic error "-std=c++11"
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<ext/rope>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e4 + 5;
using namespace std;
using __gnu_cxx::crope;
int a[maxn], dp[maxn];
bool vis[maxn][maxn];
int main()
{
int n, m; scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", a + i);
for(int i = 1; i <= n; i++){
int cnt = 0;
for(int j = i; j <= n; j++){
if(a[j] < m) cnt++;
int mid = (j - i + 2) / 2;
if(cnt < mid) vis[i][j] = 1;
}
}
for(int i = 1; i <= n; i++){
dp[i] = -inf;
for(int j = 0; j < i; j++){
if(vis[j+1][i]) dp[i] = max(dp[i], dp[j] + 1);
}
}
printf("%d\n", max(dp[n], 0));
return 0;
}
总觉得会有更快的解法,读了读别人代码,看到一个O(n)的解法:
其实对于出现的一个小于m的数,想让它所在的区间中位数大于m,需要再拉两个大于等于m的来和它组成一个区间,实际上,就算这样的数是连着的,也不会影响统计答案,因为一个小于m的数所带来的影响是一样的,那么只需要统计出来小于m的数cnt,答案就是n - 2 * cnt 了。
#pragma GCC diagnostic error "-std=c++11"
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<ext/rope>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define lowbit(x) x & (-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e4 + 5;
using namespace std;
using __gnu_cxx::crope;
int main()
{
int n, m, x, cnt = 0;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", &x);
if(x < m) cnt++;
}
printf("%d\n", max(0, n - 2 * cnt));
return 0;
}