Cake slicing UVA - 1629

记录当前待判断区域的上边界的位置-1、下边界、左边界的位置-1、右边界,减一是为了后面更加方便以及准确地判断。然后查找当前区域中的樱桃的数量,如果数量为0,那么记录当前需要裁剪的长度为无穷大(代表的含义也就是不能够在当前的区域进行进一步地裁剪),如果数量为1,那么记录当前需要裁剪的长度为0,表示当前区域已经满足要求了,不需要进行进一步地裁剪,如果数量大于等于2,那么就在当前区域尝试逐行裁剪以及逐列裁剪,同时比较并且记录裁剪得到的最小值,并返回即可,具体实现见如下代码:

package a;//实际提交的时候记得去掉包名

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    int n,m,k;
    int [][]area=new int[22][22];
    int [][][][]dp=new int[22][22][22][22];

    int Case=0;

    public void Init(){
        for(int i=0;i<22;i++){
            Arrays.fill(area[i],0);
        }
        for(int i=0;i<22;i++){
            for(int j=0;j<22;j++){
                for(int k=0;k<22;k++){
                    Arrays.fill(dp[i][j][k],-1);
                }
            }
        }
    }

    public int amountCherry(int u,int d,int l,int r){
        int amount=0;
        for(int i=u+1;i<=d;i++){
            for(int j=l+1;j<=r;j++){
                if(area[i][j]==1){
                    amount++;
                    if(amount==2) return amount;
                }
            }
        }
        return amount;
    }

    public int DP(int u,int d,int l,int r){
        if(dp[u][d][l][r]!=-1) return dp[u][d][l][r];
        int amount=amountCherry(u,d,l,r);
        if(amount==1){
            dp[u][d][l][r]=0;
            return 0;
        }
        else if(amount==0){
            dp[u][d][l][r]=(1<<20);
            return dp[u][d][l][r];
        }
        else{
            dp[u][d][l][r]=(1<<20);
            for(int i=u+1;i<d;i++){//按照行来剪
                dp[u][d][l][r]=Math.min(dp[u][d][l][r],DP(u,i,l,r)+DP(i,d,l,r)+r-l);
            }
            for(int j=l+1;j<r;j++){//按照列来剪
                dp[u][d][l][r]=Math.min(dp[u][d][l][r],DP(u,d,l,j)+DP(u,d,j,r)+d-u);
            }
        }
        return dp[u][d][l][r];
    }

    public void dealPro(){
        Scanner scan=new Scanner(System.in);
        while(scan.hasNext()){
            Init();
            n=scan.nextInt();
            m=scan.nextInt();
            k=scan.nextInt();
            for(int i=0;i<k;i++){
                int x=scan.nextInt();
                int y=scan.nextInt();
                area[x][y]=1;
            }
            Case++;
            System.out.println("Case "+Case+": "+DP(0,n,0,m));
        }
    }

    public static void main(String[] args){
        Main a=new Main();
        a.dealPro();
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值