算法提高 求最大值

博客提出一个算法问题,给定n个有序整数对ai bi,需选择部分数对,使选定数对的ai+bi之和最大,且ai之和、bi之和均非负。给出了输入输出格式、样例及数据规模约定。

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

问题描述
  给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大。并且要求你选定的数对的ai之和非负,bi之和非负。
输入格式
  输入的第一行为n,数对的个数
  以下n行每行两个整数 ai bi
输出格式
  输出你选定的数对的ai+bi之和
样例输入
5
-403 -625
-847 901
-624 -708
-293 413
886 709
样例输出
1715
数据规模和约定
  1<=n<=100
  -1000<=ai,bi<=1000

	#include <iostream>
	#include <cstring>
	using namespace std;
	//这么题目有桶排序的思想,d[]数字记录的是所有可能的结果,为-1时表示没有这个结果,为1时表示有这个结果;
	//a[]数组记录的是结果为i时a的总和,b[]数组记录的是结果为i时b的总和;
	//以200000为中点,左边的是结果小于0,右边是结果大于零。
	int a[400000] = {0};
	int b[400000] = {0};
	
	int d[400000];
	
	int main()
	{
		int i, j, x, y, t;
		
		
		int n;
		cin>>n;
		for(i = 0; i <= 400000; ++i)
		{
			d[i] = -1;
		}
		d[200000] = 1;
		for(i = 1; i <= n; ++i)
		{
			cin>>x>>y;
			t = x+y;
			if(t > 0)
			{
				for(j = 400000; j >= 0; --j)//全部扫描
				{
					if(j - t >= 0 && j-t <= 400000)
					{
						if(d[j] == 1 && d[j-t] == 1)
						{
							a[j] = max(a[j], a[j-t] + x);
							b[j] = max(b[j], b[j-t] + y); 
						}else
						{
							if(d[j] < d[j-t])
							{
								a[j] = a[j-t] + x;
								b[j] = b[j-t] + y;
							}
						}
						d[j] = max(d[j], d[j-t]);
					}
				}
			}
			
			else
			{
				for(j = 0; j < 400000; ++j)
				{
					if(j-t >= 0 && j-t <= 400000)
					{
						if(d[j]==1&&d[j-t] == 1)
						{
							a[j] = max(a[j], a[j-t] + x);
							b[j] = max(b[j], b[j-t] + y); 
						}
						if(d[j] < d[j-t])
							{
								a[j] = a[j-t] + x;
								b[j] = b[j-t] + y;
							}
						d[j] = max(d[j], d[j-t]);
					}
				}
			}
		}
		for(i = 400000; i >= 0; i--)
		{
			if(a[i] >= 0&&b[i] >= 0 &&d[i] == 1)
			{
				cout<<i-200000<<endl;
				return 0;
			}
		}
		cout<<"0"<<endl;
		return 0;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值