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 ...
随机推荐
- Spring Boot(七)扩展分析
前面的章节在分析SpringBoot启动过程中,我们发现SpringBoot使用Spring框架提供的SpringFactoriesLoader这个类,实现检索META-INF/spring.fact ...
- phpcms 最多上传 10 个附件 解决办法
修改文件:/phpcms/libs/classes/form.class.php
- Filezilla 绿色版 禁止升级 能用。
FileZilla还是挺好用的,但是如果钟情于 绿色版的话,肯定首选是 免安装绿色版.但是呢,能找到的所谓的免升级 绿色版,都不能用.只要是打开软件了,就会在你还没有设置更新之前,就已经升级号了.并且 ...
- VS2010中的sln,suo分别是什么含义
我们通过双击.sln加载出我们的工程. Visual Studio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件.为解决方案资源管理器提供显示管理文件 ...
- [OS] 信号量(Semaphore)
一个信号量S是一个整型量,除对其初始化外,它只能由两个原子操作P和V来访问.P和V的名称来源于荷兰文proberen(测试)和verhogen(增量),后面亦将P/V操作分别称作wait(), sig ...
- Spring MVC架构浅析
阅读目录 Spring MVC概述 Spring MVC框架的特点 Spring MVC工作原理 Spring MVC概述 Spring的web框架围绕DispatcherServlet设计,Disp ...
- 【codevs1404】字符串匹配 KMP
题目描述 给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度.给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个.N,M,K<=200000 输入 第一行三个数 ...
- Django 2.0 学习(06):Django 视图(进阶)
概述 Django中的特方法,该方法代表了Django的Web页面,并且视图具有特定的模板.以博客应用为例进行说明,在博客应用中应该包含下面的视图: 博客主页:显示最近的一些记录: 详细页面:单个详细 ...
- Atom Editor 插件 atom-less 的使用方法
一.下载安装 atom-less atom-less 项目在这里:https://github.com/schmuli/atom-less 安装方法请参考这篇博文:http://blog.csdn.n ...
- html的body内标签之超链接
一,先来个简单的练练手,target="_blank" 的作用是在新的tab中打开页面.href 是超链接的意思. <!DOCTYPE html> <html l ...