[BZOJ] 3810: [Coci2015]Stanovi #记忆化搜索

3810: [Coci2015]Stanovi

Time Limit: 15 Sec  Memory Limit: 64 MB
Submit: 901  Solved: 401
[Submit][Status][Discuss]

Description

 

Input

输入一行,三个整数,n, m, k
 

 

Output

输出一个数,表示最小不满意度。
 

Sample Input

3 3 2

Sample Output

1

【Hint】
见描述中的左图的分割方案,最小不满意度为4 * (2 - 2) ^ 2 + (1 - 2) ^ 2 = 1。

【数据范围】
n, m <= 300
k <= 10000

HINT 

Source

Analysis

这道题,居然是,搜索

= =其实数据范围已经暴露了

那么我们定义状态 DP[ x ][ y ][ l ][ r ][ u ][ d ] 为底和高分别为 y 和 x 的矩形,其后四个状态分别表示与海边的邻接情况,有为 1 无为 0

然后只需要从合法的状态进行转移即可

将当前这个大矩形切分成两个小矩形即可转移

不会有

这种情况,因为中间那个矩形不合法

Emmmmm

所谓合法状态就是:有一条边邻接边界

Code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 int n,m,k;
 7 long long DP[305][305][2][2][2][2];
 8 long long dp(int x,int y,int l,int r,int u,int d){
 9     if(x > y){ swap(x,y); swap(u,l); swap(d,r); }
10     if(l && !r) swap(l,r);
11     if(u && !d) swap(u,d);
12     
13     long long &p = DP[x][y][l][r][u][d];
14     if(p >= 0) return p;
15     
16     p = (long long)(x*y-k)*(x*y-k);
17     for(int i = 1;i < x;i++){
18         if(!l && !r && (!u || !d)) continue;
19         p = min(p,dp(i,y,l,r,u,0)+dp(x-i,y,l,r,0,d));
20     }
21     
22     for(int i = 1;i < y;i++){
23         if(!u && !d && (!l || !r)) continue;
24         p = min(p,dp(x,i,l,0,u,d)+dp(x,y-i,0,r,u,d));
25     }return p;
26 }
27 
28 int main(){
29     memset(DP,-1,sizeof(DP));
30     scanf("%d%d%d",&n,&m,&k);
31 //    dp(n,m,1,1,1,1);
32 //    for(int i = 1;i <= n;i++)
33 //        for(int j = 1;j <= m;j++)
34 //            for(int k = 0;k < 2;k++)
35 //                for(int l = 0;l < 2;l++)
36 //                    for(int o = 0;o < 2;o++)
37 //                        for(int p = 0;p < 2;p++)
38 //                            printf("DP[%d][%d][%d][%d][%d][%d]: %d\n",i,j,k,l,o,p,DP[i][j][k][l][o][p]);
39     printf("%lld",dp(n,m,1,1,1,1));
40     
41     return 0;
42 }
记忆化搜索DP

 

posted @ 2017-11-06 14:59  Leviaton  阅读(217)  评论(0编辑  收藏  举报