洛谷P1324 矩形分割

题目描述

出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块。

对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切割下去要花不同的代价。而且,对于一块木板,切割一次以后就被分割成两块,而且不能把这两块木板拼在一起然后一刀切成四块,只能两块分别再进行一次切割。

现在,给出从不同的线切割所要花的代价,求把整块木板分割成1×1块小方块所需要耗费的最小代价。

输入格式

输入文件第一行包括N和M,表示长N宽M的矩阵。

第二行包括N-1个非负整数,分别表示沿着N-1条横线切割的代价。

第三行包括M-1个非负整数,分别表示沿着M-1条竖线切割的代价。

输出格式

输出一个整数,表示最小代价。

输入输出样例

输入 #1复制

2 2
3
3

输出 #1复制

9

说明/提示

数据范围:

对于60%的数据,有1 ≤ N ,M≤ 100;

对于100%的数据,有1 ≤ N,M ≤ 2000。

上代码:

#include<cstdio>
#include<algorithm>//用到sort
using namespace std;
const int MAXN=2020;//毕竟刚刚2020~
int a[MAXN],b[MAXN];//横线和竖线的代价
bool cmp(int aa,int bb){return aa>bb;}//从大到小
int main(){
    int n,m,s1=1,s2=1;//s1和s2可以是a数组和b数组的指针,也可以是横纵分成的块数
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++) scanf("%d",&a[i]);
    for(int i=1;i<m;i++) scanf("%d",&b[i]);
    sort(a+1,a+n,cmp);sort(b+1,b+m,cmp);//从大到小排序
    long long ans=0;//记录答案,注意long long
    for(int i=2;i<n+m;i++){//遍历
        if(a[s1]>b[s2]) ans+=s2*a[s1++];//选择大的,这里s2表示块数,s1指针后移一位
        else ans+=s1*b[s2++];//同理,和上面相反
    }
    printf("%lld",ans);
    return 0;//华丽结束
}

### P1719 最大加权矩形 Python 解题思路 对于 P1719 最大加权矩形问题,可以采用动态规划结合前缀和的方式求解。通过构建二维前缀和数组来加速区间查询效率,进而简化计算过程。 #### 动态规划状态定义 设 `dp[i][j]` 表示以第 i 行 j 列结尾的最大子矩阵权重,则有: \[ dp[i][j]=\max \left(a_{i,j}, a_{i,j}+\sum _{k=0}^{i-1}\sum _{l=j-w+1}^{j}a[k][l]\right)[^1] \] 为了提高效率,在实际编程中会先预处理出每一列的高度范围内的累积高度值,再利用这些信息更新 DP 数组中的最优解。 #### 前缀和优化 考虑到直接枚举所有可能的子矩阵时间复杂度过高,因此引入一维前缀和辅助结构降低运算量。具体来说就是维护一个临时变量记录当前正在考察的一行内连续若干列构成区间的累加值,并不断调整起始位置直到找到全局最大值为止。 ```python def max_weight_rectangle(matrix): rows, cols = len(matrix), len(matrix[0]) # 计算每行的前缀和 prefix_sum = [[0] * (cols + 1) for _ in range(rows)] for r in range(rows): for c in range(cols): prefix_sum[r][c + 1] = prefix_sum[r][c] + matrix[r][c] result = float('-inf') # 枚举上下边界 for top in range(rows): temp_row_sums = [0] * cols for bottom in range(top, rows): # 更新当前层的累计高度 for col in range(cols): temp_row_sums[col] += matrix[bottom][col] current_max_subarray = kadane_algorithm(temp_row_sums) result = max(result, current_max_subarray) return result def kadane_algorithm(nums): """Kadane's algorithm to find the maximum subarray sum""" best_sum = current_sum = nums[0] for num in nums[1:]: current_sum = max(num, current_sum + num) best_sum = max(best_sum, current_sum) return best_sum ``` 此算法的时间复杂度主要取决于两重循环遍历所有的上界下界的组合以及调用一次 Kadane 算法 O(n),总体为 \(O(N^3)\),其中 N 是输入矩阵较小维度大小。空间复杂度则由存储前缀和所需额外开销决定,即 \(O(MN)\),M 和 N 分别代表给定网格的高度与宽度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值