问题描述
给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;
}