[BZOJ] 3810: [Coci2015]Stanovi #记忆化搜索
3810: [Coci2015]Stanovi
Time Limit: 15 Sec Memory Limit: 64 MBSubmit: 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】
见描述中的左图的分割方案,最小不满意度为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 }
转载请注明出处 -- 如有意见欢迎评论