P5948 [POI2003]Chocolate
xieyuhao2022 · · 题解
Solution
我们将题目简化为:现有集合
我们观察题目,不难得出每次切割的代价为,其数值与前面不属于同个集合的数字个数
例如,若横向切下一刀,此时巧克力变为两块,那么竖向切割时就需要切两次,即做两倍代价。以此类推,即可得出上述结论。
进一步分析,我们不难得出应优先选择数值大的进行切割。
对于同个集合,显然数值大的排序靠前更优。
对于不同集合,即不同方向上切割,后切的自然需要在原基础上多切一刀,那么数值大的会越来越大。反之,我们则需要优先选择数值大的。
因此,我们可以将两个集合合并、排序后进行操作。
时间复杂度为
Code
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e4+5; //注意开两倍大小
int n,m,tot,x_,y_;
long long ans;
struct qwq{
int val,id;
}a[N];
bool cmp(qwq x,qwq y){
return x.val>y.val;
}
int main(){
cin>>n>>m;
for(int i=1;i<n;i++){
cin>>a[i].val;
a[i].id=1;
}
for(int i=n;i<n+m-1;i++){
cin>>a[i].val;
a[i].id=2;
}
tot=n-1+m-1;
sort(a+1,a+1+tot,cmp);
for(int i=1;i<=tot;i++){ //记录出现过的不同元素
if(a[i].id==1) ans+=(y_+1)*a[i].val,x_++;
else ans+=(x_+1)*a[i].val,y_++;
}
cout<<ans<<endl;
return 0;
}