0
点赞
收藏
分享

微信扫一扫

AtCoder Regular Contest 074


 

C - Chocolate Bar

Time Limit: 2 sec / Memory Limit: 256 MB

Score : 400400 points

Problem Statement

There is a bar of chocolate with a height of HH blocks and a width of WW blocks. Snuke is dividing this bar into exactly three pieces. He can only cut the bar along borders of blocks, and the shape of each piece must be a rectangle.

Snuke is trying to divide the bar as evenly as possible. More specifically, he is trying to minimize SmaxSmax - SminSmin, where SmaxSmax is the area (the number of blocks contained) of the largest piece, and SminSmin is the area of the smallest piece. Find the minimum possible value of Smax−SminSmax−Smin.

Constraints

  • 2≤H,W≤1052≤H,W≤105

Input

Input is given from Standard Input in the following format:


HH WW


Output

Print the minimum possible value of Smax−SminSmax−Smin.

Sample Input 1 Copy

Copy


3 5


Sample Output 1 Copy

Copy


0


In the division below, Smax−Smin=5−5=0Smax−Smin=5−5=0.

AtCoder Regular Contest 074_i++

Sample Input 2 Copy

Copy


4 5


Sample Output 2 Copy

Copy


2


In the division below, Smax−Smin=8−6=2Smax−Smin=8−6=2.

AtCoder Regular Contest 074_i++_02

Sample Input 3 Copy

Copy


5 5


Sample Output 3 Copy

Copy


4


In the division below, Smax−Smin=10−6=4Smax−Smin=10−6=4.

AtCoder Regular Contest 074_i++_03

Sample Input 4 Copy

Copy


100000 2


Sample Output 4 Copy

Copy


1


Sample Input 5 Copy

Copy


100000 100000


Sample Output 5 Copy

Copy


50000


 

题意:

n*m的矩形分成三块,是的最大的-最小的差值最小。

分析:

四种情况,暴力枚举A的高度即可(另外两种竖着)

AtCoder Regular Contest 074_#include_04

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL maxcha(LL a,LL b,LL c)
{
return max(a,max(b,c))-min(a,min(b,c));
}
LL cal(LL n,LL m)
{
LL ans=1e18;
for(int i=1; i<n; i++)
{
LL h=(n-i)/2;
ans=min(ans,maxcha(i*m,h*m,(n-i-h)*m));

LL w=m/2;
ans=min(ans,maxcha(i*m,(n-i)*w,(n-i)*(m-w)));
}
//cout<<ans<<endl;
return ans;
}
int main()
{
LL n,m;
cin>>n>>m;
LL maxx=max(n,m),minn=min(n,m);
if(maxx%3==0||minn%3==0)
{
cout<<0<<endl;
}
else
{
cout<<min(cal(n,m),cal(m,n))<<endl;;
}

}

 

题意:

3 * n 个数a[1~3*n],删除 n 个数(顺序未改变).并使新的序列前n个数的和 - 后n个数的和最大。

分析:

直接用小根堆求正向(保持顺序)的n个数最大的和,保存到dp1[1~3*n],dp1[i]表示删除i-n个数的n个数最大的和(i>=n)。

直接用大根堆求逆向(保持顺序)的n个数最小的和,保存到dp2[1~3*n]。

然后,最后在n~2*n中求max{dp1[i]-dp2[i+1]}。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3*100005;
LL dp1[N],dp2[N],a[N];
priority_queue<LL,vector<LL>,greater<LL> >q1;
priority_queue<LL>q2;
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=3*n; i++)
{
scanf("%d",&a[i]);
}

LL sum=0;
for(int i=1; i<=3*n; i++)
{
sum+=a[i];
q1.push(a[i]);
dp1[i]=sum;
if(q1.size()>n)
{
sum-=q1.top();
q1.pop();
dp1[i]=sum;
}
}

sum=0;
for(int i=3*n; i>=1; i--)
{
sum+=a[i];
q2.push(a[i]);
dp2[i]=sum;
if(q2.size()>n)
{
sum-=q2.top();
q2.pop();
dp2[i]=sum;
}

}

LL ans=-1e18;
for(int i=n;i<=2*n;i++)
{
ans=max(dp1[i]-dp2[i+1],ans);
}
cout<<ans<<endl;
return 0;

}

 

举报

相关推荐

0 条评论