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

本文主要是介绍【Educational Codeforces Round 1E】【动态规划-多维DP】Chocolate Bar 矩形巧克力掰开吃的最小成本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 nm 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 nm and k to process.

Each of the next t lines contains three integers nm 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 nm 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*/


这篇关于【Educational Codeforces Round 1E】【动态规划-多维DP】Chocolate Bar 矩形巧克力掰开吃的最小成本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610472

相关文章

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现动态封禁IP的步骤指南

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG... 目录1、简述2、实现方式3、使用 fail2ban 动态封禁3.1 安装 fail2ban3.2 配

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进