使用优先对列的思想购买n天一共购买n个糖果 先对每天买糖果的花费进项排序 并将每天买糖果的额外花费分摊到每一个糖果中,最后取出从大到小排序的队列的顶部n个元素之和即为买糖果的最小花费
#include<bits/stdc++.h>
using namespace std;
const int N=305;
int ans[N][N];
//优先队列 存储买糖果的花费 从大到小排序
priority_queue<int,vector<int>,greater<int>> dp;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>ans[i][j];
}
//对每天糖果价格进行从小到大排序
sort(ans[i]+1,ans[i]+1+m);
}
// i*i
// 1 1 第一天买一个 额外花费一元
// 2 4 买两个 额外花费四元 第二个糖果额外花费3元
// 3 9 同理 第三个糖果额外花费 五元
//计算买糖果的额外花费 并将其加入每一个糖果的价格中
for(int i=1;i<=n;i++){
int cnt=1;
for(int j=1;j<=m;j++){
ans[i][j]+=cnt;
cnt+=2;
}
}
//如果每天没有剩余则一天必须买一
long long sum=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp.push(ans[i][j]);
}
//每天计划一个糖果
sum+=dp.top();
//购买后及时出队
dp.pop();
}
cout<<sum<<endl;
return 0;
}