JZOJ 5350. 【NOIP2017提高A组模拟9.7】陶陶摘苹果
题目
分析
很神奇的事情又发生了!!
很容易想到设 \(f_{i,j}\) 表示考虑前 \(i\) 个区间,已选 \(j\) 个区间且必选第 \(i\) 时能覆盖到的最多苹果数
转移 \(O(n)\) 很显然了
然后,就没了·····
什么?!!
实际上测试数据给的答案是不能不用凳子的!!!
于是悲剧了······
\(Code\)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e6 + 5 , M = 205;
int n , m , h , k , ans , fi , s[N] , f[M][M];
struct node{
int l , r;
}g[M];
bool cmp(node a , node b){return a.l < b.l ? 1 : (a.l == b.l ? a.r < b.r : 0);}
int main()
{
freopen("apple.in" , "r" , stdin);
freopen("apple.out" , "w" , stdout);
scanf("%d%d%d%d" , &n , &m , &h , &k);
int x , Mx = 0;
for(register int i = 1; i <= n; i++)
{
scanf("%d" , &x);
if (x == h) {fi++; continue;}
if (x < h) continue;
s[x - h]++;
}
for(register int i = 1; i <= m; i++)
scanf("%d%d" , &g[i].l , &g[i].r) , Mx = max(Mx , g[i].r);
sort(g + 1 , g + m + 1 , cmp);
memset(f , -0x3f3f , sizeof f);
for(register int i = 1; i <= Mx; i++) s[i] += s[i - 1];
for(register int i = 1; i <= m; i++)
{
f[i][0] = 0 , f[i][1] = s[g[i].r] - s[g[i].l - 1];
for(register int j = 2; j <= min(i , k); j++)
for(register int l = 1; l < i; l++)
{
if (f[l][j - 1] < 0) continue;
int sum = s[g[i].r];
if (g[l].r >= g[i].l) sum -= s[g[l].r];
else sum -= s[g[i].l - 1];
f[i][j] = max(f[i][j] , f[l][j - 1] + sum);
}
}
for(register int i = k; i <= m; i++) ans = max(ans , f[i][k]);
printf("%d" , ans);
}