uva 1629

1629 - Cake slicing

Time limit: 3.000 seconds

A rectangular cake with a grid of m * n <tex2html_verbatim_mark>unit squares on its top needs to be sliced into pieces. Several cherries are scattered on the top of the cake with at most one cherry on a unit square. The slicing should follow the rules below:

  1. each piece is rectangular or square;
  2. each cutting edge is straight and along a grid line;
  3. each piece has only one cherry on it.

For example, assume that the cake has a grid of 3 * 4 <tex2html_verbatim_mark>unit squares on its top, and there are three cherries on the top, as shown in the figure below.

<tex2html_verbatim_mark>

One allowable slicing is as follows.

=6in <tex2html_verbatim_mark>

For this way of slicing, the total length of the cutting edges is 4+2=6.

Another way of slicing is

=6in <tex2html_verbatim_mark>

In this case, the total length of the cutting edges is 3+2=5.

Given the shape of the cake and the scatter of the cherries, you are supposed to find out the least total length of the cutting edges.

Input

The input file contains multiple test cases. For each test case:

The first line contains three integers, n <tex2html_verbatim_mark>, m <tex2html_verbatim_mark>and k <tex2html_verbatim_mark>(1nm20) <tex2html_verbatim_mark>, where n * m <tex2html_verbatim_mark>is the size of the grid on the cake, and k <tex2html_verbatim_mark>is the number of the cherries.

Then k <tex2html_verbatim_mark>lines follow. Each line has two integers indicating the position of the unit square with a cherry on it. The two integers show respectively the row number and the column number of the unit square in the grid.

All integers in each line should be separated by blanks.

Output

Output an integer indicating the least total length of the cutting edges.

Sample Input

3 4 3
1 2
2 3
3 2

Sample Output

Case 1: 5

比较经典的一个题目,记忆化搜索。状态 d[u][d][l][r] 表示切上边为u,下边为d,左边为l,右边为r的矩形是的最少消耗。一开始没有想到状态。

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define INF 1000000
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define MAXN 21
int ma[MAXN][MAXN];
int n, m, k;
int p[MAXN][MAXN][MAXN][MAXN];

int Judge(int u, int d, int l, int r)
{
    int t = 0;
    repu(i, u + 1, d + 1)
      repu(j, l + 1, r + 1)
       if(ma[i][j]) t++;
    return t;
}

int dp(int u, int d, int l, int r)
{
    if(p[u][d][l][r] != -1) return p[u][d][l][r];
    int t = Judge(u, d, l, r);
    if(t == 1) return p[u][d][l][r] = 0;
    if(t == 0) return p[u][d][l][r] = INF;
    int minn = INF;
    repu(i, u + 1, d) minn = min(minn, dp(u, i, l, r) + dp(i, d, l, r) + (r - l));
    repu(i, l + 1, r) minn = min(minn, dp(u, d, i, r) + dp(u, d, l, i) + (d - u));
    return p[u][d][l][r] = minn;
}

int main()
{
    int kase = 0;
    while(~scanf("%d%d%d", &n, &m, &k))
    {
        _cle(ma, 0);
        _cle(p, -1);
        int x, y;
        repu(i, 0, k) {
          scanf("%d%d", &x, &y);
          ma[x][y] = 1;
        }
        printf("Case %d: %d\n", ++kase, dp(0, n, 0, m));
    }
    return 0;
}

 
时间: 2024-08-05 23:40:41

uva 1629的相关文章

UVA 1629 Cake slicing

题解: 记忆化搜索 如何判断每个区域只有一个点?转化为区间和,只要区间和为1即可 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,

UVa 1629 Cake slicing (记忆化搜索)

题意:一个矩形蛋糕上有好多个樱桃,现在要做的就是切割最少的距离,切出矩形形状的小蛋糕,让每个蛋糕上都有一个樱桃,问最少切割距离是多少. 析:很容易知道是记忆化搜索,我们用dp[u][d][l][r]来表示,上界是u,下界是d,左边是l,右边是r,然后不断切割,不过要注意切的时候是按缝隙切, 缝隙多一条,那么我们可以补上一条,用0来补齐,然后就进行计算就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #in

UVA 1629 - Cake slicing(记忆化搜索)

记忆化搜索, 枚举所有的切割方式dp[r1][c1][r2][c2]表示(r1, c1) (r2, c2)之间的蛋糕切割所需要的最小花费count_num用来计算(r1, c1) (r2, c2)之间有多少个草莓递推边界当count_num为1是返回0 init()为对草莓数的一个预处理,使得在O(1)的时间内可以计算区域内的草莓数 总状态数为m * n * m * n决策有n + m种 时间复杂度为O((n + m) * n * n * m * m) /*583ms*/ 1 #include<

uva 1629切蛋糕(dp)

有一个n行m列的网格蛋糕,上面有一些樱桃,求使得每块蛋糕上都有一个樱桃的切割最小长度 思路:dp. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue&

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

[UVa] Palindromes(401)

UVA - 401 Palindromes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDED

uva 401.Palindromes

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=342 题目意思:给出一段字符串(大写字母+数字组成).判断是否为回文串 or 镜像串 or 回文镜像串 or 什么都不是.每个字母的镜像表格如下 Character Reverse Character Reverse Character Reverse A A M M Y Y B