BZOJ 2430 [Poi2003]Chocolate(贪心+归并排序)
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2430
【题目大意】
有一块n*m的矩形巧克力,准备将它切成n*m块。
巧克力上共有n-1条横线和m-1条竖线,你每次可以沿着其中的一条横线或竖线将巧克力切开,
无论切割的长短,沿着每条横线切一次的代价依次为y1,y2,…,yn-1,
而沿竖线切割的代价依次为x1,x2,…,xm-1,求将巧克力切割为小单位快需要最小代价
【题解】
我们发现题目等价于有两个集合X,Y,里面有一些数字,现在将两个集合进行归并排序,
每个数字的代价为其数值与(前面不属于同个集合的数字个数+1)的乘积,求最小代价。
我们发现对于同个集合,显然数值大的排序靠前更优,对于不同集合的数,
我们考虑当他们相邻时,交换位置相当于总代价改变他们之间的差值,
显然也是大的数字靠前代价更小一些,所以我们按照从大到小进行归并排序,同时计算答案即可。
【代码】
#include <cstdio> #include <algorithm> using namespace std; const int N=10010; int n,m,a[N],b[N]; bool cmp(int a,int b){return a>b;} int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<n;i++)scanf("%d",&a[i]); for(int i=1;i<m;i++)scanf("%d",&b[i]); sort(a+1,a+n+1,cmp); sort(b+1,b+m+1,cmp); int posa=1,posb=1,ans=0; for(int i=1;i<n+m-1;i++){ if(posb>m&&posa<=n||a[posa]>b[posb])ans+=a[posa++]*posb; else ans+=b[posb++]*posa; }printf("%d\n",ans); }return 0; }
愿你出走半生,归来仍是少年