CF-1132 C.Painting the Fence

題目大意:如今有n個柵欄板,p個工人,每一個工人能夠塗一段區間的柵欄板,問若是僱傭p-2個工人,最多能夠塗多少塊柵欄板。ios

作法:先求出q個工人能塗得最多木板數,並統計每一個木板被塗的次數。求被塗一次的木板個數和被塗兩次的木板個數的前綴和。spa

暴力枚舉選擇去掉哪兩個工人,而且看看能刪掉幾個木板。便可code

#include<iostream>
#include<cstdio>
#define maxn 5010
using namespace std;
int n,p,l[maxn],r[maxn],a[maxn],sum1[maxn],sum2[maxn],ans,cur;
int main(){
    scanf("%d%d",&n,&p);
    for(int i=1;i<=p;i++)scanf("%d%d",&l[i],&r[i]);
    for(int i=1;i<=p;i++)
        for(int j=l[i];j<=r[i];j++)
            a[j]++;
    for(int i=1;i<=n;i++){
        sum1[i]=sum1[i-1];
        sum2[i]=sum2[i-1];
        if(a[i]==1)sum1[i]++;
        if(a[i]==2)sum2[i]++;
        if(a[i])cur++;
    }
//    for(int i=1;i<=n;i++)printf("%d ",sum1[i]);puts("");
//    for(int i=1;i<=n;i++)printf("%d ",sum2[i]);puts("");
    for(int i=1;i<=p;i++){
        for(int j=i+1;j<=p;j++){
            int now=cur;
            int l1=l[i],r1=r[i],l2=l[j],r2=r[j];
            if(l1>l2){
                swap(l1,l2);
                swap(r1,r2);
            }
            if(r1<l2){//兩個區間互不覆蓋 
                now-=sum1[r1]-sum1[l1-1];
                now-=sum1[r2]-sum1[l2-1];
            }
            else{
                int l3=max(l1,l2);
                int r3=min(r1,r2);
                now-=sum1[r1]-sum1[l1-1];
                now-=sum1[r2]-sum1[l2-1];
                now-=sum2[r3]-sum2[l3-1];
            }
            ans=max(ans,now);
        }
    }
    printf("%d\n",ans);
    return 0;
}
相關文章
相關標籤/搜索