码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2298: [HAOI2011]problem a DP

时间:2019-02-21 09:41:26      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:bzoj   code   最大   namespace   注意   begin   turn   转化   数字   

链接

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

bzoj2298: [HAOI2011]problem a DP

标签:bzoj   code   最大   namespace   注意   begin   turn   转化   数字   

原文地址:https://www.cnblogs.com/dsrdsr/p/10410259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!