题目描述
pigstd 有一堆数,他想在这么多数中选出若干个数排成一列,记为 x 1 , x 2 , ⋯ , x p x_1 ,x_2 ,⋯,x_p x1,x2,⋯,xp(p 为数的个数)。这一列数合法当且仅当满足以下条件:
p i g s t d pigstd pigstd 想知道,在所有合法的数列中,所有在这个数列中的数之和最大是多少。
输入格式
第一行两个整数 n , k n,k n,k。
接下来 n 行,每行两个整数 a i , b i a_i,b_i ai,bi,表示 p i g s t d pigstd pigstd 有 b i b_i bi个 a i a_i ai 。
不保证 a i a_i ai互不相同,若有 a i a i ai
相同则累加其个数计算。
输出格式
一行一个整数,表示在每一种排列中,所有在这个排列中的数的最大的和。
若没有合法的排列,则只输出 N O NO NO。
输入输出样例
输入 #1复制
4 3
1 5
2 4
3 3
0 2
输出 #1复制
6
说明/提示
【样例 1 说明】
当 p i g s t d pigstd pigstd 的排列为: 0 , 3 , 0 , 3 0,3,0,3 0,3,0,3 或 3 , 0 , 3 , 0 3,0,3,0 3,0,3,0 时,总和最大,为 6 6 6。
【数据规模与约定】
对于 100% 的数据, 1 ≤ n ≤ 1 0 6 , 0 ≤ k , a i ≤ 1 0 6 , 1 ≤ b i ≤ 1 0 6 1≤n≤10^6 ,0≤k,a_i≤10^6,1≤b_i≤10^6 1≤n≤106,0≤k,ai≤106,1≤bi≤106。
本题采用捆绑测试。
解题思路
由我一系列的推导发现:你只能在这个序列中选两种不同的数。。。
SO,这道题就可以用模拟水了。
简单的,暴力的,枚举 i i i,若i与i+k都存在,即组成一种方案,然后他们的总和为 ( i + i + k ) ∗ m i n ( a [ i ] , a [ i + k ] ) (i+i+k)*min(a[i],a[i+k]) (i+i+k)∗min(a[i],a[i+k])。。。
PS:特判 k = = 1 k==1 k==1 的情况 (^ _ ^)
代码
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
long long n,k,x,y,xx,ans,maxn,a[1000100];
bool flag=0;
int main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&x,&y);
maxn=max(maxn,x);
a[x]+=y;
}
for(int i=0;i<=maxn-k;i++)
{
if(a[i]&&a[i+k])
{
if(k!=0)
{
flag=1;
xx=(i+i+k)*min(a[i],a[i+k]);
ans=max(ans,xx);
}
else if(a[i]>1)
{
flag=1;
xx=i*a[i];
ans=max(ans,xx);
}
}
}
if(flag==1)
printf("%lld",ans);
else
printf("NO");
}