bzoj 1084 DP
首先对于m==1的情况非常容易处理(其实这儿因为边界我错了好久。。。),直接DP就好了,设f[i][k]为这个矩阵前i个选k个矩阵的最大和,那么f[i][k]=max(f[j][k-1]+sum[j+1][i]),那么对于m==2的时候类似与m=1的时候,设w[i][j][k]为左面的一行前i个中,右面的一行前j个中,一共选k个矩阵能选取得最大矩阵。
那么转移也比较明显,有一下几种转移
w[i][j][k]=max(w[i-1][j][k],w[i][j-1][k])这种情况代表什么都不选。
w[i][j][k]=max(w[ii][j][k-1]+sum[ii+1][i][0])这种情况代表在左面一行重新确定i这个位置如何选取。
类似的w[i][j][k]=max(w[i][jj][k-1]+sum[jj+1][j][1])这种情况代表在右面一行重新确定i这个位置如何选取。
当i==j的时候w[i][j]=max(w[ii][ii]+sum[ii+1][i][2]),这样就代表选了一个占两行的矩形,然后注意枚举的边界就可以了。
反思:开始我的想法是w[i][k]代表两行矩阵前i个选k个矩阵的最大值,我们可以知道选取矩阵的方法肯定是若干段只选取一行的组合,然后由选取两行的隔开,那么我们可以枚举i代表在i出选取占两行的矩形(这个矩形的长可以为0),那么w[i][k]=max(w[j][k]+f[j+1][ii]+sum[ii][i]),这个转移就是先枚举上一次的断点,然后后枚举上一断点到i的情况,就是一段只选取一行的加上一个占两行的最大值,那么首先要处理每一行的f[i][j][k]值,代表i,j段选取k个矩阵的最大值。后来因为转移的时候枚举边界特别麻烦,没有调出来,再仔细想想之后发现这种转移由于状态数太少,没办法准确的表达每一个状态,所以转移起来非常麻烦,所以就加了一维,可以准确的表达所有状态,而且转移十分方便,复杂度也降低了一个k(因为上一种方法需要枚举左右两行各选多少矩形),总之,还是自己太弱了。。。
/**************************************************************
Problem: 1084
User: BLADEVIL
Language: C++
Result: Accepted
Time:88 ms
Memory:1672 kb
****************************************************************/ //By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100
#define maxm 20 using namespace std; int n,m,k;
int a[maxn][maxn],sum[maxn][maxn],f[maxn][maxm],w[maxn][maxn][maxm]; int main(){
scanf("%d%d%d",&n,&m,&k);
sum[][]=sum[][]=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
scanf("%d",&a[i][j]),sum[i][j]=sum[i-][j]+a[i][j];
if (m==){
memset(f,,sizeof(f));
for (int i=;i<=n;i++) {
f[i][]=;
for (int l=;l<=k;l++){
f[i][l]=f[i-][l];
for (int j=;j<i;j++){
f[i][l]=max(f[i][l],f[j][l-]+sum[i][]-sum[j][]);
}
}
}
printf("%d\n",f[n][k]);
} else {
memset(w,,sizeof(w));
for (int i=;i<=n;i++) {
for (int j=;j<=n;j++){
w[i][j][]=;
for (int l=;l<=k;l++){
w[i][j][l]=max(w[i-][j][l],w[i][j-][l]);
for (int ii=;ii<i;ii++)
w[i][j][l]=max(w[i][j][l],w[ii][j][l-]+sum[i][]-sum[ii][]);
for (int jj=;jj<j;jj++)
w[i][j][l]=max(w[i][j][l],w[i][jj][l-]+sum[j][]-sum[jj][]);
if (i==j)
for (int jj=;jj<i;jj++)
w[i][i][l]=max(w[i][i][l],w[jj][jj][l-]+sum[i][]-sum[jj][]+sum[j][]-sum[jj][]);
}
}
}
printf("%d\n",w[n][n][k]);
}
return ;
}
bzoj 1084 DP的更多相关文章
- [BZOJ 1084] [SCOI2005] 最大子矩阵 【DP】
题目链接:BZOJ - 1084 题目分析 我看的是神犇BLADEVIL的题解. 1)对于 m = 1 的情况, 首先可能不取 Map[i][1],先 f[i][k] = f[i - 1][k]; ...
- 【SCOI2005】 最大子矩阵 BZOJ 1084
Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤2 ...
- bzoj 3622 DP + 容斥
LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...
- BZOJ 1084: [SCOI2005]最大子矩阵 DP
1084: [SCOI2005]最大子矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n* ...
- BZOJ 1084 最大子矩阵 dp
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1084 题目大意: 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分 ...
- 【BZOJ 1084】 1084: [SCOI2005]最大子矩阵 (DP)
1084: [SCOI2005]最大子矩阵 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第 ...
- 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)
题链 http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩 ...
- bzoj 1084: [SCOI2005]最大子矩阵【dp】
分情况讨论,m=1的时候比较简单,设f[i][j]为到i选了j个矩形,前缀和转移一下就行了 m=2,设f[i][j][k]为1行前i个,2行前j个,一共选了k个,i!=j的时候各自转移同m=1,否则转 ...
- BZOJ - 1003 DP+最短路
这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...
随机推荐
- 华为oj----iNOC产品部-杨辉三角的变形 .
此题提供三种方法,第一种,一开始就能想到的,设置一个足够大的数组存储生成的杨辉三角,然后进行判断就行,此方法参见:华为oj iNOC产品部-杨辉三角的变形 另一种方法是采用递归: 三角形的每行的个数为 ...
- 关于如何解决PHPCMS V9内容搜索显示不全问题解决方案
站长朋友们都晓得只要是开源的PHP程序都会有漏洞存在.如果想完美的建站就需要自己去研究打补丁了.最近很多站长联系小编咨询用phpcms建站当在首页搜索内容的时候有的居然搜索不到.小编感到很是奇怪于是就 ...
- sql server 带输入输出参数的分页存储过程(效率最高)
create procedure proc_page_withtopmax( @pageIndex int,--页索引 @pageSize int,--每页显示数 @pageCount int out ...
- [转]MATLAB cell数据类型
细胞型数据类型(cell)使不同类型和不同维数的数组可以共存,细胞型数组实际上可以认为是一种以任意形式的数组为分量的多维数组. 1.细胞型数据的定义 1)直接赋值定义:细胞型变量在定义时需要使用大括号 ...
- 【刷题】洛谷 P3809 【模板】后缀排序
题目背景 这是一道模板题. 题目描述 读入一个长度为 \(n\) 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...
- [LOJ #2473] [九省联考2018] 秘密袭击coat
题目链接 洛谷. LOJ,LOJ机子是真的快 Solution 我直接上暴力了...\(O(n^2k)\)洛谷要\(O2\)才能过...loj平均单点一秒... 直接枚举每个点为第\(k\)大的点,然 ...
- PC蓝牙通信C#代码实现
PC蓝牙通信C#代码实现 这篇文章主要为大家详细介绍了PC蓝牙通信C#代码实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了C#实现PC蓝牙通信代码,供大家参考,具体内容如下 ...
- JavaScript如何获得input元素value的值
在JavaScript中获取input元素value的值: 方法一: <!DOCTYPE html> <html> <head> <meta charset= ...
- 组合框控件 -- CComboBox
组合框控件 -- CComboBox 组合框其实就是把一个编辑框和一个列表框组合到了一起,分为三种:简易(Simple)组合框.下拉式(Dropdown)组合框和下拉列表式(Drop List)组合框 ...
- HDU4027 线段树
Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K ...