【Educational Codeforces Round 1E】【动态规划-多维DP】Chocolate Bar 矩形巧克力掰开吃的最小成本

原创 2015年11月19日 12:58:48
E. Chocolate Bar
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You have a rectangular chocolate bar consisting of n × m single squares. You want to eat exactly k squares, so you may need to break the chocolate bar.

In one move you can break any single rectangular piece of chocolate in two rectangular pieces. You can break only by lines between squares: horizontally or vertically. The cost of breaking is equal to square of the break length.

For example, if you have a chocolate bar consisting of 2 × 3 unit squares then you can break it horizontally and get two 1 × 3 pieces (the cost of such breaking is 32 = 9), or you can break it vertically in two ways and get two pieces: 2 × 1 and 2 × 2 (the cost of such breaking is 22 = 4).

For several given values n, m and k find the minimum total cost of breaking. You can eat exactly k squares of chocolate if after all operations of breaking there is a set of rectangular pieces of chocolate with the total size equal to k squares. The remaining n·m - ksquares are not necessarily form a single rectangular piece.

Input

The first line of the input contains a single integer t (1 ≤ t ≤ 40910) — the number of values n, m and k to process.

Each of the next t lines contains three integers n, m and k (1 ≤ n, m ≤ 30, 1 ≤ k ≤ min(n·m, 50)) — the dimensions of the chocolate bar and the number of squares you want to eat respectively.

Output

For each n, m and k print the minimum total cost needed to break the chocolate bar, in order to make it possible to eat exactly ksquares.

Sample test(s)
input
4
2 2 1
2 2 3
2 2 2
2 2 4
output
5
5
4
0
Note

In the first query of the sample one needs to perform two breaks:

  • to split 2 × 2 bar into two pieces of 2 × 1 (cost is 22 = 4),
  • to split the resulting 2 × 1 into two 1 × 1 pieces (cost is 12 = 1).

In the second query of the sample one wants to eat 3 unit squares. One can use exactly the same strategy as in the first query of the sample.


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=0,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
int f[32][32][52];
void DP()
{
	//初始化
	MS(f,63);
	for(int i=0;i<=30;i++)
	{
		for(int j=0;j<=30;j++)f[i][j][0]=0;
	}
	for(int i=1;i<=30;i++)
	{
		for(int j=1;j<=30;j++)if(i*j<=50)f[i][j][i*j]=0;
	}
	//状态转移
	for(int i=1;i<=30;i++)
	{
		for(int j=1;j<=30;j++)
		{
			int top=min(i*j,50);
			for(int k=1;k<=top;k++)//总共要切的份数
			{
				for(int u=1;u<=i/2;u++)//横着切
				{
					int topp=min(u*j,k);
					for(int kk=0;kk<=topp;kk++)
					{
						gmin(f[i][j][k],f[u][j][kk]+f[i-u][j][k-kk]+j*j);
					}
				}
				for(int v=1;v<=j/2;v++)//竖着切
				{
					int topp=min(v*i,k);
					for(int kk=0;kk<=topp;kk++)
					{
						gmin(f[i][j][k],f[i][v][kk]+f[i][j-v][k-kk]+i*i);
					}
				}
			}
		}
	}
}
int main()
{
	DP();int n,m,k;
	scanf("%d",&casenum);
	for(casei=1;casei<=casenum;casei++)
	{
		scanf("%d%d%d",&n,&m,&k);
		printf("%d\n",f[n][m][k]);
	}
	return 0;
}
/*
【trick&&吐槽】
1,不要让自己太懒惰呀,这道水题就是差1分钟AC >_<
2,没有AC的原因是我把数组给爆了!初始化的边界问题也要多多注意呀!RE时返回的可能并不是RE

【题意】
有T(4e4)组询问。
对于每组询问,问你,我们想要在一个n(30)*m(30)的大巧克力中,
吃掉一个大小为k(1<=k<=min(n*m,50))的小巧克力的最小体力成本。

吃巧克力为什么需要体力成本呢?
因为如果巧克力太大了,我们就要把它掰开。
对于一个i*j的巧克力,我们可以横着沿[1,i-1]的线掰开,也可以纵着沿[1,j-1]的线掰开。
横着掰开的成本是掰开巧克力的宽度,也就是j;纵着掰开的成本是掰开巧克力的长度,也就是i。

【类型】
DP

【分析】
我们直接枚举
1,大巧克力的长
2,大巧克力的宽
3,吃巧克力的大小
4,横着还是竖着切,在哪里切
5,一侧吃的巧克力的大小
6,另一侧吃的巧克力的大小
这道题就做完啦
时间复杂度为O(n*m*k*(n+m)*k)
大概为30*30*50*60*50=1.35e8
AC完全没有压力!这样就AC啦!


具体来说——
就是定义f[i][j][k]表示我们在一个i*j的巧克力块中吃一个大小恰好为k的巧克力的成本
数组大小为[31][31][51]
初始化f[i][j][0]=f[i][j][i*j] 注意i*j可能达到900,然而我们数组才开到50,于是这里要特判下。
做CF的时候我就是因为这里的错误没有做到AC >_<
状态转移方程为——
gamx(f[i][j][k],f[u][j][kk]+f[i-u][j][k-kk]+j*j);u∈[1,j/2],u表示横着切的位置,我们只需要枚举小的那一半即可,成本自然是j*j
gamx(f[i][j][k],f[i][v][kk]+f[i][j-v][k-kk]+i*i);v∈[1,i/2],v表示竖着切的位置,我们只需要枚举小的的一半即可,成本自然是i*i
kk表示在这一半吃的巧克力的数量,显然kk∈[0,min(u*j,k)]或kk∈[0,min(i*v,k)];
这样更新一下,我们永远是先更新小的矩阵,再更新大的矩形。后效性一定有保证。每个状态都得到了更新。

于是最后直接输出f[n][m][k]即可。

【时间复杂度&&优化】
O(n*m*k*(n+m)*k)

【数据】
10 10 9

*/


版权声明:题解中哪里写错请一定要指出来QwQ 转载还请注明下出处哦,谢谢^_^

相关文章推荐

hihocoder 1274 自行车架 多维dp

描述 小Hi的宿舍楼下有一块用于停自行车的区域。平时自行车都停得非常杂乱,于是楼长打算去买一排自行车架用来停车。自行车架一般有P个槽,每个槽的两侧都可以停入自行车;但是一个槽位同时只能有一侧停入自行...

Educational Codeforces Round 1 E Chocolate Bar(dp)

题意: 给定N∗M(N,M≤30)的巧克力,现在要吃掉K≤50的面积的给定N*M(N,M\le 30)的巧克力, 现在要吃掉K\le 50的面积的 且要求吃掉的一定是长方形,剩余部分的形状不...
  • lwt36
  • lwt36
  • 2016年01月19日 22:32
  • 370

Educational Codeforces Round 1 E.Chocolate Bar(DP)

题目大意:初始有一块n*m的巧克力,每次只能沿一条直线切成两块矩形的巧克力,花费为所切边长的平方。问:最终得到面积和为k的巧克力的最小花费为多少? dp[n][m][k]表示用n*m的矩形得到面积和...

【Codeforces Round 332 (Div 2)A】【水题】A. Patrick and Shopping 遍历三元环的最小成本

A. Patrick and Shopping time limit per test 1 second memory limit per test 256 megabytes...

【Codeforces Round 364 (Div 2)F】【暴力 双连通分量求桥】Break Up n点m边最多割2边最小成本使得S与T不联通

F. Break Up time limit per test 3 seconds memory limit per test 256 megabytes input...

Codeforces 598E Chocolate Bar (dp)

@(K ACMer) 题意: 给你一个n∗mn*m的矩形,你每次可以横着或者竖着切割,每次切割的消耗是切割长度的平方,要得到总共面积为k的一个矩形集合,需要的最少切割消耗是多少? 分析: 很容...

codeforces 710E Generate a String [dp]【动态规划】

题目链接:http://codeforces.com/problemset/problem/710/E ————————————————-. E. Generate a String time ...

Educational Codeforces Round 2 E - Lomsat gelral(树形dp+启发式合并)

题意: 给定N≤105的一棵树,每个节点有一个颜色,求出每个节点所在子树中出现最多的颜色的颜色ID和给定N\le 10^5的一棵树, 每个节点有一个颜色, 求出每个节点所在子树中出现最多的颜色的颜...
  • lwt36
  • lwt36
  • 2016年01月23日 23:25
  • 418

Educational Codeforces Round 2 E.Lomsat gelral(树形dp)

从叶子节点向上更新控制颜色即可,但是必须用map映射而且要将小树合并到大树当中,否则会MLE...

Educational Codeforces Round 19-E. Array Queries(简单dp)

题目链接 题目大意: 给你n个数,ai∈[1,n]a_i\in[1,n] qq个查询,每次给你pp,kk。 有操作:p−>p+a[p]+kp -> p + a[p] + k 问经过多少次这样...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Educational Codeforces Round 1E】【动态规划-多维DP】Chocolate Bar 矩形巧克力掰开吃的最小成本
举报原因:
原因补充:

(最多只允许输入30个字)