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 ...
随机推荐
- 【Docker 命令】- rm命令
docker rm :删除一个或多少容器 语法 docker rm [OPTIONS] CONTAINER [CONTAINER...] OPTIONS说明: -f :通过SIGKILL信号强制删除一 ...
- 安装django 提示ImportError: No module named setuptools
安装django前要先安装setuptools 先安装一些必要的包,否则会报错:Python build finished, but the necessary bits to build these ...
- Android Studio类中实现Serializable自动生成serialVersionUID
1.File -> Settings... -> Editor -> Inspections -> Serialization issues -> Serializabl ...
- CentOS 安装MariaDB
1.安装 #同时安装mariadb和mariadb-server [root@bigdata-senior01 yum.repos.d]# yum -y install mariadb mariadb ...
- [洛谷P4688][Ynoi2016]掉进兔子洞
题目大意:给定一个$n(n\leqslant10^5)$序列,$m(m\leqslant10^5)$个询问,每个询问给出$l_1,r_1,l_2,r_2,l_3,r_3$.令$s$为该三个区间的交集的 ...
- 洛谷3800:Power收集——题解
https://www.luogu.org/problemnew/show/P3800 可以把游戏界面理解成一个N行M列的棋盘,有K个格子上有P点,其价值为val(i,j) 初始灵梦可以选择在第一行的 ...
- 51NOD 1773:A国的贸易——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773 参考1:FWT讲解 https://www.cnblogs.com ...
- Linux上安装Oracle11g
1.首先是挂盘 1.1 Linux硬盘挂载步骤:查看磁盘 先查看目前机器上有几块硬盘,查看命令有两种: 命令1:# fdisk –l 命令2:# dmesg | grep sd 其中:fdisk命令说 ...
- Kindle 电子书相关的工具软件【转】
这里是与 Kindle 电子书相关的工具软件.它们可以帮助我们解决在日常使用电子书时所可能遇到的问题,比如 kindle 管理工具.kindle 转换工具.kindle电子书制作工具.kindle 推 ...
- bzoj2761: [JLOI2011]不重复数字(hash)
题目大意:给出N个数,要求把其中重复的去掉,只保留第一次出现的数.例如,给出的数为1 2 18 3 3 19 2 3 6 5 4,其中2和3有重复,去除后的结果为1 2 18 3 19 6 5 4. ...