JZOJ6367. 【NOIP2019模拟2019.9.25】工厂(factory)

49 篇文章 0 订阅

Description

  • 给定n个区间,将它们分成q组,使得每一组中的区间的交集不为空,所有组的交集大小之和最大。
  • 保证题目至少存在一种合法的分配方案。
    p<=n<=200

Solution

  • 区间问题很容易想到的套路:考虑包含的区间之间的关系,通过某种转换将包含的区间去掉,然后就可以变成相交或相离的区间,排序后就可以很方便地DP。
  • 这题也不例外。
  • 如果一个区间x包含区间y,那么要么区间x单独一个,要么区间x跟y在一组。
  • 因为如果x不是单独的话,去掉x会变优,加进y的组里也不会变劣。
  • 有了这个性质就可以很好地DP了。
  • 对于不包括其他区间的区间,排序后按顺序选就好了。
  • 而其他的区间如果加进去对答案也没有影响。
  • 剩下没有考虑过的贪心让他们选最长的就好了。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define maxn 205
using namespace std;

int n,m,i,j,k,l[maxn],r[maxn],tot1,p[maxn],tot2,q[maxn],bz[maxn];
int f[maxn][maxn];
int cmp1(int i,int j){return l[i]<l[j];}
int cmp2(int i,int j){return r[i]-l[i]>r[j]-l[j];}

int main(){
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]);
	for(i=1;i<=n;i++) {
		int tp=1;
		for(j=1;j<=n;j++) if (i!=j&&!bz[j]&&l[i]<=l[j]&&r[j]<=r[i])	
			tp=0;
		if (tp) p[++tot1]=i; else q[++tot2]=i,bz[i]=1;
	}
	sort(p+1,p+1+tot1,cmp1);
	sort(q+1,q+1+tot2,cmp2);
	memset(f,128,sizeof(f));
	f[0][0]=0;
	for(i=0;i<tot1;i++) for(j=0;j<m;j++) if (f[i][j]>=0){
		for(k=i+1;k<=tot1&&r[p[i+1]]>l[p[k]];k++)
			f[k][j+1]=max(f[k][j+1],f[i][j]+r[p[i+1]]-l[p[k]]);
	}
	int sum=0,ans=0;
	for(i=0;i<=min(tot2,m);i++,sum+=r[q[i]]-l[q[i]])
		ans=max(ans,sum+f[tot1][m-i]);
	printf("%d",ans);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值