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

【BZOJ2298】【HAOI2011】problem a 动态规划

时间:2015-04-10 15:38:30      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:bzoj2298   haoi2011   problem-a   动态规划   

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44979323");
}

题解:

一句话 (a,b) 可以理解成一个线段 (a,n?b]
然后排个序去下重,最后一个线段的权值 x 就是表示 这 x 人互不冲突,一起算。

然后动态规划求若干条不相交线段的权值最大值,最后用总人数减去就行了。
fi 表示有 i 人时最大权值。
fseqi r=max  (    fsi r    ,    fsi l+si x    );

然后一个线段的权值不能单纯看有多少人说的相同,因为可以有100个人都说了同一个线段 (a,a+1] ,那么显然这个线段的权值不是100,而是1。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
using namespace std;
int n,m,p;
struct Eli
{
    int l,r,x;
    void read()
    {
        scanf("%d%d",&l,&r);
        r=n-r;
    }
    bool operator < (const Eli &A)const
    {return r==A.r?l<A.l:r<A.r;}
}s[N];
int f[N];
int main()
{
    freopen("test.in","r",stdin);

    int i;

    scanf("%d",&n);
    for(i=1;i<=n;i++)s[i].read();
    sort(s+1,s+n+1);
    for(i=1;i<=n;i++)
    {
        if(s[i].l>=s[i].r)continue;
        if(s[i].l!=s[i-1].l||s[i].r!=s[i-1].r)
            s[++m].l=s[i].l,s[m].r=s[i].r,s[m].x=1;
        else s[m].x++;
    }

    for(i=1;i<=m;i++)
    {
        while(p<s[i].l)f[p+1]=max(f[p+1],f[p]),p++;
        s[i].x=min(s[i].x,s[i].r-s[i].l);
        f[s[i].r]=max(f[s[i].r],f[s[i].l]+s[i].x);
    }
    while(p<s[m].r)f[p+1]=max(f[p+1],f[p]),p++;
    printf("%d\n",n-f[s[m].r]);

    return 0;
}

【BZOJ2298】【HAOI2011】problem a 动态规划

标签:bzoj2298   haoi2011   problem-a   动态规划   

原文地址:http://blog.csdn.net/vmurder/article/details/44979323

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