zoukankan      html  css  js  c++  java
  • UVA 1629 Cake slicing 记忆化搜索

                                      Cake slicing

    A rectangular cake with a grid of m×n 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 unit squares on its top, and there are three
    cherries on the top, as shown in the figure on the right corner.
    One allowable slicing is as follows.
    For this way of slicing, the total length of the cutting edges is 4+2=6.
    Another way of slicing is
    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, m and k (1 ≤ n, m ≤ 20), where n × m is the size of the
    grid on the cake, and k is the number of the cherries.
    Then k 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

    题意:

      给你一个n行m列的网格,上面有一些蛋糕。每次可以用一刀沿着网格线切成两块,并且只能够直切不能拐弯。

      要求最后每一块蛋糕上恰好有一个樱桃,

      且切割线总长度最小。

    题解:

      

      我们记忆花爆搜就好了

      设定dp[row][col][x][y] 在当前以点(x,y)为左上角的蛋糕块的最小切割次数,且保证分的块数尽量多

      我们接下来枚举切那个地方就好了

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 25, M = 100, inf = 1e9+7, mod = 1e9+7;
    int T,n,m,k,mp[N][N],dp[N][N][N][N],vis[N][N][N][N];
    int dfs(int row,int col,int x,int y) {
        if(vis[row][col][x][y]) return dp[row][col][x][y];
        int& ret = dp[row][col][x][y];
        ret = inf;
        vis[row][col][x][y] = 1;
        if(row==1&&col==1) {
            ret = mp[x][y]?0:inf;
            return ret;
        }
        int cnt = 0;
        for(int i=x;i<=row+x-1;i++)
            for(int j=y;j<=y+col-1;j++) if(mp[i][j]) cnt++;
        if(cnt == 1) {
            ret = 0;
            return ret;
        }
        if(cnt == 0) return ret;
        for(int i=y+1;i<=y+col-1;i++) {
            ret = min(ret,dfs(row,i-y,x,y)+dfs(row,col-i+y,x,i)+row);
        }
        for(int i=x+1;i<=x+row-1;i++) {
            ret = min(ret,dfs(i-x,col,x,y)+col+dfs(row-i+x,col,i,y));
        }
        return ret;
    }
    int main() {
        int x,y,cas = 1;
        while(scanf("%d%d%d",&n,&m,&k)!=EOF) {
            memset(mp,0,sizeof(mp));memset(dp,-1,sizeof(dp));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=k;i++) scanf("%d%d",&x,&y), mp[x][y] = 1;
            printf("Case %d: %d
    ",cas++,dfs(n,m,1,1));
        }
        return 0;
    }
  • 相关阅读:
    EasyUI--Alert()
    asp.net 页面之间传值的几种方式
    c# 的类成员
    c# protected public private internal
    C#中的多态性
    c# 静态成员和实例成员的区别
    js确认框confirm()用法实例详解
    JS中的switch case
    分分钟用上C#中的委托和事件
    Asp.net MVC中关于@Html标签Label、Editor使用
  • 原文地址:https://www.cnblogs.com/zxhl/p/5437051.html
Copyright © 2011-2022 走看看