bzoj2298: [HAOI2011]problem a DP
链接
https://www.lydsy.com/JudgeOnline/problem.php?id=2298
思路
把一个人的话转化为区间的线段,显然是\([a_{i},n-b_{i}]\)
然后找最大的不相交,不覆盖的最多线段数量
注意是有重复的数字,所以不是单纯的线段覆盖
f[i]=max(f[i],f[j]+max(区间长度,重复数字个数))
最后输出n-f[n]就好了
代码
/**************************************************************
Problem: 2298
User: 3010651817
Language: C++
Result: Accepted
Time:1200 ms
Memory:6672 kb
****************************************************************/
#include <bits/stdc++.h>
#define Pair pair<int,int>
using namespace std;
const int N=1e5+7;
int n,f[N];
Pair a[N];
vector<int > p[N];
map<Pair,int> hasH;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;++i) {
scanf("%d%d",&a[i].first,&a[i].second);
a[i].first++,a[i].second=n-a[i].second;
if(a[i].second>n || a[i].first<1 || a[i].first>a[i].second) continue;
if(++hasH[a[i]]==1) p[a[i].second].push_back(a[i].first);
}
for(int i=1;i<=n;++i) {
f[i]=f[i-1];
for(std::vector<int >::iterator it=p[i].begin();it!=p[i].end();++it)
f[i]=max(f[i],f[*it-1]+min(i-*it+1,hasH[make_pair(*it,i)]));
}
printf("%d\n",n-f[n]);
return 0;
}