bzoj1237 [SCOI2008]配对 贪心结论+插数dp

如果没有相同的数不能配的情况下,就直接排序后对位配就可以了,由单调性很好证明

然后如果有相同不能配的情况,那配对的数字在排完序的数列里一定不会跨度太大,因为离得越远意味着差值越大

然后就需要定量考虑到底要跨多少

只有相同的才会产生跨度,如果相同的有连续2个 就是交叉相连,如果3个,就有两种情况 ,如果4个,显然两个X更优

以后的就用X逼近,剩下3个就连成キ的两种情况就可以了


码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
long long n,i,j,f[99999][5],a[99999],b[99999];
int main()
{
	scanf("%lld",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a[i+2],&b[i+2]);		
	}
	sort(a+3,a+3+n);	sort(b+3,b+3+n);
	f[0][0]=f[1][0]=1000000000000000000;
	f[2][0]=0;
for(i=3;i<=n+2;i++)//0:全都配过了 1:最后一对没配 2: 最后两对没配 
{
	f[i][0]=min(min(f[i-3][0]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i-2])+abs(a[i-2]-b[i]),f[i-3][0]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i])+abs(a[i-2]-b[i-1])),f[i-2][0]+abs(a[i]-b[i-1])+abs(b[i]-a[i-1]));	
	if(a[i]!=b[i])	
	{
		f[i][0]=min(f[i-1][0]+abs(a[i]-b[i]),f[i][0]);
	}
}
if(f[n+2][0]==1000000000000000000)printf("-1");
else	printf("%lld",f[n+2][0]);	
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值