poj2442

本文探讨了POJ2442问题的解决策略,首先从特殊情况m=2入手,通过排序找到最小和。接着,利用堆结构避免重复计算,通过vis数组或额外变量g来控制移动方向,确保不重复选择答案。文章提供了详细的算法思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先考虑m=2的情况
将数组排好序 最小的和肯定是a_1+b_1
假设这一个答案为a_i,b_j下一个答案的可能会加入a_i+1,b_j和a_i,b_j+1
把所有可能的下一个加入一个堆
为了避免一个答案被加入两次 ,可以用vis数组或者直接在加入堆时加入一个变量g表示有无移动过j 如果移动过后面就不能移i只能移j,可以保证不会重复选到

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int t,n,m;
struct node
{
	int a[2005];
}s[105];
int p;
struct mes
{
	int j,k;
	bool g;
	bool operator >(const mes b)const
	{
		return s[p].a[j]+s[p+1].a[k]<s[p].a[b.j]+s[p+1].a[b.k];
	}
	bool operator <(const mes b)const
	{
		return s[p].a[j]+s[p+1].a[k]>s[p].a[b.j]+s[p+1].a[b.k];
	}
};
mes make_mes(int x,int y,int z)
{
	mes ret;
	ret.j=x,ret.k=y,ret.g=z;
	return ret;
}
priority_queue<mes>q;
int b[2005];
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&m,&n);
		for(int i=1;i<=m;++i)
		{
			for(int j=1;j<=n;++j)
			{
				scanf("%d",&s[i].a[j]);
			}
			sort(s[i].a+1,s[i].a+n+1);
		}
		for(int i=1;i<m;++i)
		{
			p=i;
			while(!q.empty())q.pop();
			q.push(make_mes(1,1,0));
			for(int j,k,t=1;t<=n;++t)
			{
				j=q.top().j;
				k=q.top().k;
				bool ab=q.top().g;
				q.pop();
				b[t]=s[i].a[j]+s[i+1].a[k];
				if(!ab)q.push(make_mes(j+1,k,ab));
				q.push(make_mes(j,k+1,1));
			}
			for(int j=1;j<=n;++j)
			{
				s[i+1].a[j]=b[j];
			}
		}
		for(int i=1;i<=n;++i)
		{
			printf("%d ",s[m].a[i]);
		}
		printf("\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值