BZOJ 3810 [Coci2015]Stanovi

这讲真就是一篇显得自己认真做题的博客

因为真的比较习惯将培训所有的题都放到一篇博客中,又因为暑假好多培训,所以单题很少,这也是从博客中摘出来的

题目链接

如果合法,一定有一条贯穿整个矩形的线;

dp[i][j][t]长度为i,宽度为j,面向大海的边的状态是t这样划分最小差异度是啥;、

然后因为一定要贯穿,可以一分为二:dp[i][j][t]=左边+右边;

其中t:

t==1 只有一面环海:

img

显然如果我们要将其分成两部分,只能:

img

for(int i=1;i<n;i++) ans=min(ans,work(i,m,1)+work(n-i,m,1));
    return f[n][m][t]=ans;

t2 && t4 有2面环海:
t==2:

img

如果要分成两部分的话,可以横着分,也可以竖着分:

img

    for(int i=1;i<n;i++) ans=min(ans,work(i,m,2)+work(n-i,m,1));//竖着分?
    for(int i=1;i<m;i++) ans=min(ans,work(n,i,2)+work(m-i,n,1));//横着分?

t==4:

img

img

同样可以横着分和竖着分:

for(int i=1;i<n;i++) ans=min(ans,work(i,m,4)+work(n-i,m,4));
for(int i=1;i<m;i++) ans=min(ans,work(n,i,1)+work(n,m-i,1));

t==3:三面环海:

img

img

同样有两种划分方法:

for(int i=1;i<n;i++) ans=min(ans,work(i,m,3)+work(n-i,m,4));
for(int i=1;i<m;i++) ans=min(ans,work(n,i,2)+work(n,m-i,2));

CODE:

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long

using namespace std;

inline int read(){
	int ans=0;
	char last=' ',ch=getchar();
	while(ch>'9'||ch<'0') last=ch,ch=getchar();
	while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
	if(last=='-') ans=-ans;
	return ans;
}

int n,m,k;
ll ans;
ll f[310][310][5];

ll hs(int x,int y,int t){
	if(f[x][y][t]!=-1) return f[x][y][t];
	ll ans=((ll)x*y-k)*((ll)x*y-k);
	
	if(t==1){
		for(int i=1;i<x;i++) ans=min(ans,hs(i,y,1)+hs(x-i,y,1));
		return f[x][y][t]=ans;
	}
	if(t==3){
		for(int i=1;i<x;i++) ans=min(ans,hs(i,y,3)+hs(x-i,y,2));
		for(int i=1;i<y;i++) ans=min(ans,hs(x,i,4)+hs(x,y-i,4));
		return f[x][y][t]=ans;
	}
	if(t==2){
		for(int i=1;i<x;i++) ans=min(ans,hs(i,y,2)+hs(x-i,y,2));
		for(int i=1;i<y;i++) ans=min(ans,hs(x,i,1)+hs(x,y-i,1));
		return f[x][y][t]=ans;
	}
	if(t==4){
		for(int i=1;i<x;i++) ans=min(ans,hs(i,y,4)+hs(x-i,y,1));
		for(int i=1;i<y;i++) ans=min(ans,hs(x,i,4)+hs(y-i,x,1));
		return f[x][y][t]=ans;
	}
}

int main(){
	n=read();
	m=read();
	k=read();
	memset(f,-1,sizeof(f));
	ans=1e18;
	for(int i=1;i<n;i++) ans=min(ans,hs(i,m,3)+hs(n-i,m,3));
	for(int i=1;i<m;i++) ans=min(ans,hs(m-i,n,3)+hs(i,n,3));
	printf("%lld",ans);
	return 0;
}
posted @ 2019-09-08 15:27  Sweetness  阅读(170)  评论(0编辑  收藏  举报