bzoj3810[Coci2015]Stanovi 记忆化搜索

168 篇文章 0 订阅
2 篇文章 0 订阅

一开始没想到,不过这题模型不是很明显。。估计我也想不出来= =
设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<<60
using 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值