【贪心结论】
【贪心结论】
排序
Stacking of Goods
https://codeforces.com/gym/105358/problem/J
【结论】交叉相乘
计算
\[c_1 \times 0 + c_2 \times w_1 + c_3 \times (w_1+w_2) + c_4 \times (w_1+w_2+w_3) + ... + c_n \times (w_1+w_2+...+w_{n-1})
\]
的最小值
->排序方式:a.w * b.c > b.w * a.c
代码
const int N=1e5+10;
int n;
struct node{
i64 w,v,c;
}g[N];
void solve(){
cin>>n;
for(int i=1;i<=n;i++) cin>>g[i].w>>g[i].v>>g[i].c;
sort(g+1,g+n+1,[&](node a,node b)->bool{
return a.w*b.c>a.c*b.w;
});
vector<i64> res(n+2,0);
for(int i=1;i<=n;i++){
res[i]=res[i-1]+g[i].w;
}
i64 ans1=0;
for(int i=1;i<=n;i++){
ans1+=g[i].v;
}
i64 ans2=0;
for(int i=2;i<=n;i++){
ans2+=res[i-1]*g[i].c;
}
i64 ans=ans1-ans2;
cout<<ans<<endl;
}
New Year's Gifts
https://codeforces.com/contest/2182/problem/E
【额外贡献】
将必须计算的贡献在一开始求和减去,后面只操作需要额外花费的贡献
题目大意

思路
定义额外花费w=z-y
盒子要优先满足额外花费最多的
金币要优先满足额外花费最少的
注意这里有个文字陷阱:每个朋友都必须购买礼物(那就是y的总和必须被花)(hyw
代码
struct node{
int x;
i64 y,z,w;
};
void solve(){
cin>>n>>m>>k;
vector<int> a(m+1,0);
for(int i=1;i<=m;i++) cin>>a[i];
vector<node> p(n+1);
i64 sum=0;
for(int i=1;i<=n;i++){
cin>>p[i].x>>p[i].y>>p[i].z;
p[i].w=p[i].z-p[i].y;
sum+=p[i].y;
}
//后面只算z-y差值
k-=sum;
sort(p.begin()+1,p.end(),[&](node x,node y)->bool{
return x.w>y.w;
});
//先满足盒子
multiset<int> s;
vector<bool> st(n+1,0); //统计是不是已经送了
int cnt1=0;
for(int i=1;i<=m;i++) s.insert(a[i]);
for(int i=1;i<=n&&!s.empty();i++){
auto idx=s.lower_bound(p[i].x); //找到大于等于第一个
if(idx!=s.end()){
s.erase(idx);
st[i]=1;
cnt1++;
}
}
//然后满足金币
int cnt2=0;
for(int i=n;i>=1;i--){
if(!st[i]){
if(k>=p[i].w){
k-=p[i].w;
cnt2++;
st[i]=1;
}
}
}
int ans=cnt1+cnt2;
cout<<ans<<endl;
}

浙公网安备 33010602011771号