首页 > 其他分享 >【0909 B组】切蛋糕 题解

【0909 B组】切蛋糕 题解

时间:2023-12-19 12:24:26浏览次数:40  
标签:int 题解 sum MAXN 蛋糕 美味 0909 dp

原题链接:切蛋糕

题意

给定一个 \(n\) 行 \(m\) 列的蛋糕,问横着切 \(i\) 刀,竖着切 \(j\) 刀后美味度最小的蛋糕的美味度尽可能大。一块蛋糕的美味度为它所含有的小块的美味度之和。

数据范围:\(1 \le n,m \le 14\)。

思路

看到数据范围,我们可以考虑一种类似于状态压缩的思想,先枚举每一行切的位置的所有情况。对于每一种情况设 \(dp_{i,j}\) 表示枚举到第 \(i\) 列,在列上一共切了 \(j\) 刀时美味度可以达到的最大值。那么可以先预处理处 \(num_{s,L,R}\) 表示在行的状态为 \(s\) 的情况下,在 \(L\) 列和 \(R\) 列分别切一刀时的美味度的最小值。那么则可以推出状态转移方程为:\(dp_{i,j}= \max(dp_{i,j},dp_{k-1,j-1}+num_{i,k})\)。枚举行的情况复杂度 \(O(2^{n})\),预处理和 \(dp\) 转移均为 \(O(n^{3})\),总时间复杂度 \(O(2^{n}n^{3})\),可以通过。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define inf_db
#define ls id << 1
#define rs id << 1 | 1
#define re register
#define endl '\n'
typedef pair <int,int> pii;
const int MAXN = 15;
int n,m,a[MAXN][MAXN],sum[MAXN][MAXN],dp[MAXN][MAXN],ans[MAXN][MAXN],lastp,lastq;
int dis[MAXN][MAXN][MAXN][MAXN],num[MAXN][MAXN];
inline int calc(int x,int y,int p,int q){return sum[x][y] + sum[p - 1][q - 1] - sum[p - 1][y] - sum[x][q - 1];}
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(re int i = 1;i <= n;i++)
		for(re int j = 1;j <= m;j++)
		{
			scanf("%lld",&a[i][j]);
			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
		}
	for(re int i = 1;i <= n;i++) for(re int j = 1;j <= m;j++)
	for(re int p = 1;p <= i;p++) for(re int q = 1;q <= j;q++) dis[i][j][p][q] = calc(i,j,p,q);
	for(re int i = 0;i < (1 << (n - 1));i++)
	{
		for(re int L = 1;L <= m;L++)
			for(re int R = L;R <= m;R++)
			{
				int lastj = 1;num[L][R] = 1e9;
				for(re int j = 1;j <= n;j++)
				{
					if(!(i & (1 << (j - 1))) && (j != n)) continue;
					num[L][R] = min(num[L][R],dis[j][R][lastj][L]);
					lastj = j + 1;
				}
			}
		for(re int j = 0;j <= m;j++) for(re int k = 0;k <= m;k++) dp[j][k] = -1e9;
		dp[0][0] = 1e9;
		for(re int j = 1;j <= m;j++) for(re int k = 1;k <= j;k++)
		for(re int p = 1;p <= j;p++) dp[j][p] = max(dp[j][p],min(dp[k - 1][p - 1],num[k][j]));
		int id = __builtin_popcount(i) + 1;
		for(re int k = 1;k <= m;k++) ans[id][k] = max(ans[id][k],dp[m][k]);
	} 
	for(re int i = 1;i <= n;i++) 
	{
		for(re int j = 1;j <= m;j++) printf("%lld ",ans[i][j]);
		puts("");
	}	
	return 0;
}

标签:int,题解,sum,MAXN,蛋糕,美味,0909,dp
From: https://www.cnblogs.com/Creeperl/p/17913433.html

相关文章

  • Cyclic Operations 题解
    前言看这道题有好多巨佬都是用Tarjan来做的,在这里讲一个自认为比较简单的做法,(不到\(30\)行)。题意题意比较难讲,建议自己去看一下翻译,在这里不多赘述。思路首先看到题目中间给的一个每一次操作的式子:\(a_{l_{i}}=l_{(i\modk)+1}\)。仔细观察这个式子后会发现,其实每一次......
  • P4630 [APIO2018] 铁人两项 题解
    今天学习了圆方树,并且做了一道和这道题很像的题,于是就又来做了一下这道题。题意给定一张不保证连通的无向图。求有多少个点对\((a,b,c)\)满足\(a\)到\(c\)的简单路径上经过了点\(b\)。思路显然圆方树。点双缩点过后构造一颗圆方树,然后考虑如何计算答案。圆方树有一个实......
  • [ABC315G] Ai + Bj + Ck = X (1 <= i, j, k <= N) 题解
    原题链接:ABC315G前置知识:扩展欧几里得算法。如果还不会扩欧的话,建议先去做这道题。题意给定\(n,a,b,c,k\)。求有多少个\(x,y,z(x,y,z\len)\)满足\(ax+by+cz=k\)。思路首先看到题目给出的方程式:\(ax+by+cz=k\)。我们会发现很像扩欧板子中的:\(ax+by=k\)。只不过又多了一......
  • [ABC318G] Typical Path Problem 题解
    原题链接:ABC318G显然是圆方树。点双缩点过后建立一颗以点\(c\)为根节点的圆方树,考虑什么情况是合法的。从点\(a\)开始往上跳直到跳到点\(c\),如果中间走过了某一个方点并且这个方点与\(b\)点有直接连边,那么就是合法的;否则不合法。证明:如果路径中所经过的方点和\(b\)点......
  • [ABC318F] Octopus 题解
    前言赛时只做到了E题,赛后才来补的F题,还没做出来,看来还是我太菜了。看了题解过后感觉这道题的思路特别巧妙,于是就来写了这篇题解。题意简述一下题意。有\(n\)个宝藏位置分别在\(a_{i}\),另外有一只章鱼有\(n\)条触手,每条触手的长度为\(b_{i}\)。求有多少个点\(k\)......
  • Two-Colored Dominoes 题解
    前言看了这道题的几篇题解,感觉讲的方法都比较麻烦,这里讲一个感觉比较简单的方法。思路首先判断是否有解。计算一下每一行和每一列的牌的数量,只要有一个是奇数就无解,否则有解。证明显然,偶数一定可以分成两组,在纸上模拟一下也可以得出。其次看如何构造。对于竖着的牌,显然只对每......
  • P3071 [USACO13JAN] Seating G 题解
    题意:维护两个操作,区间推平,求连续\(0\)的个数为\(x\)的最前位置。线段树。因为需要求连续\(0\)的个数,所以维护区间左边连续\(0\)的最大个数,区间右边连续\(0\)的最大个数以及区间连续\(0\)的最大个数。注意修改的时候要看是修改为\(1\)还是修改为\(0\)。查询的时......
  • P2664 树上游戏 题解
    原题链接:P2664。题意:给定一棵树,每个点都有一个颜色\(c_{i}\)。对于每一个点\(i\),求出\(\sum_{j=1}^{n}s(i,j)\)的值。其中\(s(i,j)\)表示点\(i\)到点\(j\)的颜色数量。路径相关,考虑点分治。假设当前的重心为\(u\),那么对\(u\)自己的贡献就是\(u\)到\(u\)的所有......
  • [ABC328F] Good Set Query 题解
    复习了一下边带权并查集板子。设\(d_{x}\)表示当前点到它所在连通块根节点的距离。合并点\(x\)和点\(y\)所在两个连通块时需要更新\(d\)。因为将\(x\)点所在连通块的根节点的父亲节点设为了\(y\)点所在连通块的根节点,所以有\(x\toy\toFind(y)=x\toFind(x)\to......
  • P6370 [COCI2006-2007#6] KAMEN 题解
    原题链接:P6370思路题意不多赘述。首先这道题的\(60\)分暴力很好打,直接按题目中的操作做即可,时间复杂度\(O(nr)\)。考虑优化暴力。我们会发现很多次石头的起始点为同一列的情况,其实每一次下落的轨迹是差不多的。具体来讲应该是第一次下落的轨迹一定包含了后面每一次的轨迹。......