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;
}

posted @ 2019-02-21 08:04  ComplexPug  阅读(121)  评论(0编辑  收藏  举报