P8298 [COCI2012-2013#2] POPUST 题解
题目
题目大意
有
思路
考虑贪心。
zhx说的好,遇事不决先排序 。
因为不管点菜的顺序,所以我们将
这样就够了?显然不是。例如这么一组数据
4
1 2
114514 15
1919810 8
1145141919810 45
如果我们按照上面的方法计算的话,例如当
也就是说,对于后面的
综合两种情况
/* author: Rmax | Always_maxx */
#include<bits/stdc++.h>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define int long long
#define bug cout << "I love sport" <<"\n";
#define BYALWAYS_MAXX return 0
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
inline int read() {
int x=0,f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
return f ? -x : x;
}
struct rmax{
int a,b;
}food[N];
int n,ans[N];//ans 为答案数组
int sum[N],mina[N],cha[N];// sum 为 b[i] 的前缀和,mina 为 a[i] 的最小值,cha 为 a[i]-b[i] 的最小值
inline bool cmp(rmax x,rmax y){
return x.b < y.b ;//排序
}
inline void init()
{
n=read();
for(int i=1;i<=n;i++) food[i].a=read(),food[i].b=read();//读入
sort(food+1,food+n+1,cmp);//按 b 排序
cha[0] = INF;
memset(mina,INF,sizeof(mina));//预处理 mina 数组
for(int i=1;i<=n;i++)
{
sum[i] = sum[i-1]+food[i].b;//前缀和数组
cha[i] = min(cha[i-1],food[i].a-food[i].b);//求最小差值
}
for(int i=n;i;i--)
mina[i] = min(mina[i+1],food[i].a);//反向处理
for(int i=1;i<=n;i++)
ans[i] = min(sum[i-1]+mina[i],sum[i]+cha[i-1]);//求最小值
}
signed main()
{
init();
for(int i=1;i<=n;i++)
printf("%lld\n",ans[i]);//只负责输出的主函数
BYALWAYS_MAXX;
}
思路来源为这位 int 家族的 dalao