题目描述
pigstd 有一堆数,他想在这么多数中选出若干个数排成一列,记为 x1,x2,⋯ ,xp(p 为数的个数)。这一列数合法当且仅当满足以下条件:p≥2。令 yi=xi+1−xi(特别的,yp=x1−xp),如果把 y1 到 yp 按 y1,y2,⋯ ,yp 的顺序排成一圈,那么每两个相邻的数互为相反数且绝对值都为 k。pigstd 想知道,在所有合法的数列中,所有在这个数列中的数之和最大是多少。
输入格式
第一行两个整数 n,k。接下来 n 行,每行两个整数 ai,bi,表示 pigstd 有 bi 个 ai。不保证 ai 互不相同,若有 ai 相同则累加其个数计算。
输出格式
一行一个整数,表示在每一种排列中,所有在这个排列中的数的最大的和。若没有合法的排列,则只输出 NO。
输入
4 3
1 5
2 4
3 3
0 2
输出
6
思路
为什么这次月赛这么水
其实这题很简单,注意2个点:
- 读懂题目才可以做对题目,你品,你细品
- 3年OI一场空,不开long long见祖宗
题目相当于求出一个长度>=2的序列,要一个大,一个小,一个大,一个小,就像山脉一样(一起爬山吗),最后一个要小的,最前面一个要大的(反过来也行),求出最大和的序列。
代码:
#include<iostream>
#include<algorithm>
#include<map>
#include<cstdio>
using namespace std;
int a[1000001];
bool b;
long long n,k,um=0,o,mx;
int main()
{
cin>>n>>k;
for (int i=0;i<n;i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
a[x]+=y;
mx=max(x,mx);
}
for (long long i=mx;i>=k;i--)
{
if (a[i-k]!=0&&a[i]!=0)
{
if (i==i-k)
{
if (a[i]==1) continue;
um=max(um,a[i]*i);
b=1;
}
else um=max(um,min(a[i],a[i-k])*(i+i-k)),b=1;
}
}
if (b==0)
{
cout<<"NO";
return 0;
}
cout<<um;
return 0;
}