【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 转载还请注明下出处哦,谢谢^_^

动态规划DP问题分类和经典题型

解题关键: 理解结构特征,抽象出状态,写成状态转移方程。 动态规划理念: 1.最优化原理    1951年美国数学家R.Bellman等人,根据一类多阶段问题的特点,把多阶...
  • u010398493
  • u010398493
  • 2016年10月13日 20:48
  • 4652

非常好的动态规划总结,DP总结

总结的非常好,谢谢作者。 http://cppblog.com/menjitianya/archive/2015/10/23/212084.html 目录   一、动态规...
  • mmc2015
  • mmc2015
  • 2017年06月22日 09:31
  • 2725

UVa 1099 分巧克力 ACM解题报告(状压dp)

这题切巧克力,首先看见这题数据很小,n小于等于15,可以直接压缩状态,全集就是(1 首先要把每个集合内的巧克力的面积和求出来,sum[s]=sigma(a[i]),s&(1 状态转移方程是dp(s...
  • Miracle_ma
  • Miracle_ma
  • 2015年02月12日 22:49
  • 633

dp动态规划分类详解

转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码...
  • Renl1000
  • Renl1000
  • 2016年11月11日 10:31
  • 2332

从DP到基于树结构的动态规划立体匹配算法

如图1所示,分别是几种基本方法得到的视差图。其中AD往往比Census在物体边缘上的处理更好一些,边缘明显清晰,但是AD得到的噪声太多,AD-Census在物体边缘上的效果是二者的折中,但噪声更少,整...
  • xujx09
  • xujx09
  • 2017年03月30日 15:55
  • 820

我的总结-动态规划(DP)

说到动态规划,最开始接触到这类型的题目是在教练上课的时候放了杭电OJ的名为“数塔”的题目,其实仅靠着没有任何算法基础而且对电脑编程处理问题的方式还不熟悉只会暴力加模拟的思维方式,着实没有除开暴力之外的...
  • mo1302267724
  • mo1302267724
  • 2015年04月06日 20:50
  • 1121

【算法之动态规划(一)】动态规划(DP)详解

一、基本概念 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E...
  • cangchen
  • cangchen
  • 2015年04月14日 17:09
  • 19939

Codeforces Round #406 (Div. 2):C. Berzerk(记忆化搜索解决博弈问题)

C. Berzerk time limit per test 4 seconds memory limit per test 256 megabytes input standard in...
  • Jaihk662
  • Jaihk662
  • 2017年03月24日 15:23
  • 793

【动态规划DP,二维动归】poj1651,Multiplication Puzzle

http://poj.org/problem?id=1651 有N张写有数字的卡片排成一行,按一定次序从中拿走N-2张(第1张和最后一张不能拿),每次只拿一张,取走一张卡片的同时,会得到一个...
  • mmc2015
  • mmc2015
  • 2015年08月06日 19:46
  • 1414

【DP专辑】ACM动态规划总结

转载请注明出处,谢谢。   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15...
  • Scythe666
  • Scythe666
  • 2016年03月18日 11:10
  • 2035
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Educational Codeforces Round 1E】【动态规划-多维DP】Chocolate Bar 矩形巧克力掰开吃的最小成本
举报原因:
原因补充:

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