首先对于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的更多相关文章

  1. [BZOJ 1084] [SCOI2005] 最大子矩阵 【DP】

    题目链接:BZOJ - 1084 题目分析 我看的是神犇BLADEVIL的题解. 1)对于 m = 1 的情况, 首先可能不取 Map[i][1],先 f[i][k] = f[i - 1][k];   ...

  2. 【SCOI2005】 最大子矩阵 BZOJ 1084

    Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤2 ...

  3. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  4. BZOJ 1084: [SCOI2005]最大子矩阵 DP

    1084: [SCOI2005]最大子矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n* ...

  5. BZOJ 1084 最大子矩阵 dp

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1084 题目大意: 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分 ...

  6. 【BZOJ 1084】 1084: [SCOI2005]最大子矩阵 (DP)

    1084: [SCOI2005]最大子矩阵 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第 ...

  7. 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)

    题链 http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩 ...

  8. 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,否则转 ...

  9. BZOJ - 1003 DP+最短路

    这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...

随机推荐

  1. css那些事儿3 列表与浮动

    一  列表 列表默认为行内块元素,具有宽高,当一个非块元素是无法应用宽高的,比如a 1 有序列表 有ol li组成,其中li为列表项,列表的ol子元素务必为li元素标签,li子内容支持列表任意嵌套,有 ...

  2. 身份证验证php

    /**  * 验证身份证号  * @param $vStr  * @return bool  */ function isCreditNo($vStr) {     $vCity = array(   ...

  3. extract函数行结果

    $arr2=array('a'=>'aaaa','b'=>'bbbb','c'=>'cccc','d'=>'dddd','e'=>'eeeee','b'=>'fff ...

  4. PHP中Session和Cookie的探究

    一.Session (1)Session的由来以及介绍 Session:在计算机中,尤其是在网络应用中,称为“会话控制”,生存时间为用户在浏览某个网站时,从进入网站到关闭这个网站所经过的这段时间,也就 ...

  5. [剑指Offer] 51.构建乘积数组

    题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...

  6. JSON字符串书写

      { "XXX公司": [ { "name": "IT部", "mebers": [ { "维护人员&quo ...

  7. JAVA开发工作流程

    阶段 0 :拟出一个计划 决定在后面的过程中采取哪些步骤,思考整个开发任务如何实现,分步骤建立“路标”,这样可以帮助自己开发时一步一个脚印的逐步完成,有效的防止自己在开发过程中迷失方向. 阶段 1 : ...

  8. [USACO06NOV]玉米田Corn Fields 状压DP

    题面: 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他的 ...

  9. POJ3630:Phone List——题解

    http://poj.org/problem?id=3630 简单的trie树问题,先添加,然后每个跑一边看中途有没有被打上结束标记即可. #include<cstdio> #includ ...

  10. 淘淘搜索结果中image属性中有多张图片的处理

    solr引擎查询某一个 商品后的结果中,image字段中如果有多张图片路径(用逗号隔开)时,前台会不 显示图片,解决方法如下: package com.taotao.portal.pojo; publ ...