bzoj3810[Coci2015]Stanovi 记忆化搜索

来源:互联网 发布:淘宝网-淘我喜欢首页 编辑:程序博客网 时间:2024/05/01 11:34

一开始没想到,不过这题模型不是很明显。。估计我也想不出来= =
设f[x][y][a][b][c][d]表示当前分割长度为x,宽为y的矩形,a,b,c,d表示是否与四边接触,核心转移就是把一个矩形分成两半然后继续往下做。

[您的好友:(卡常狂魔)已上线]
min速度太慢不能用,换成if会好很多。。
然后我发现,把define变成直接写居然会快上200多ms。。woc。。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)#define inf 1ll<<60using namespace std;const int N=1e5+5;typedef long long ll;int n,m,k;ll f[310][310][2][2][2][2];inline ll dfs(int x,int y,int a,int b,int c,int d){    if (x>y)    {        swap(x,y);        int aa=c,bb=d,cc=b,dd=a;        a=aa,b=bb,c=cc,d=dd;        if (a>b)swap(a,b);        if (c>d)swap(c,d);    }    if (f[x][y][a][b][c][d]!=-1)return f[x][y][a][b][c][d];    if (!a&&!b&&!c&&!d)return f[x][y][a][b][c][d]=inf;    ll ans=1ll*(x*y-k)*(x*y-k);    if (a+b+c>0&&a+b+d>0)    for(int i=1;i<x;i++)    {        ll tmp=dfs(i,y,a,b,c,0)+dfs(x-i,y,a,b,0,d);        if (tmp<ans)ans=tmp;    }    if (a+c+d>0&&b+c+d>0)    for(int i=1;i<y;i++)    {        ll tmp=dfs(x,i,a,0,c,d)+dfs(x,y-i,0,b,c,d);        if (tmp<ans)ans=tmp;    }    return f[x][y][a][b][c][d]=ans;}int main(){    memset(f,-1,sizeof(f));    scanf("%d%d%d",&n,&m,&k);    printf("%lld\n",dfs(n,m,1,1,1,1));    return 0;}
原创粉丝点击