关闭

bzoj[SCOI2005]最大子矩阵

标签: bzoj动态规划
321人阅读 评论(0) 收藏 举报
分类:

这题m只有2,所以一开始就想到了分情况。m=1的情况很容易想,就是普通动规枚举所有情况输出。m=2的情况一开始本来想先求出第一列,再得出第二列,这样只能过6个点,因为无法判断到两列应该分开当作两个矩阵,还是合成为一个矩阵(你可能会说,只要当一个矩阵就好,但在枚举中,有如i=1(行),k=2(矩阵数)的情况,这时必须分成两个)所以只能两个同步求,如果两行枚举到一样的就判断一下合成一行。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a[110][5],f[110][110][20],sum[110][5];
int main()
{
    int n,m,K;
    scanf("%d%d%d",&n,&m,&K);
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            sum[i][j]=sum[i-1][j]+a[i][j];
        }
    memset(f,0,sizeof(f));
    if(m==1)
    {
        f[1][1][1]=a[1][1];
        for(int i=2;i<=n;i++)
            for(int k=1;k<=K;k++)
            {
                f[i][1][k]=f[i-1][1][k];
                for(int j=i-1;j>=k-1;j--)
                    f[i][1][k]=max(f[i][1][k],(sum[i][1]-sum[j][1])+f[j][1][k-1]);
            }
        printf("%d\n",f[n][1][K]);
    }
    else
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=K;k++)
                {
                    f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
                    for(int ii=i-1;ii>=k-1;ii--)f[i][j][k]=max(f[i][j][k],(sum[i][1]-sum[ii][1])+f[ii][j][k-1]);
                    for(int jj=j-1;jj>=k-1;jj--)f[i][j][k]=max(f[i][j][k],(sum[j][2]-sum[jj][2])+f[i][jj][k-1]);
                    if(i==j)
                    {
                        for(int t=i-1;t>=k-1;t--)
                            f[i][j][k]=max(f[i][j][k],(sum[i][1]-sum[t][1])+(sum[j][2]-sum[t][2])+f[t][t][k-1]);
                    }
                }
        printf("%d\n",f[n][n][K]);
    }
    return 0;
}
1
3
查看评论

bzoj1084: [SCOI2005]最大子矩阵-DP

现在已经能自然的想到分类讨论了。 注意到m=1或者2,当m=1时,是普通的最大连续字段和,只不过是k个: 设f[i][j]表示前i个数中取出j个矩形的最大和 转移: 选:f[i][j]=max{f[i1][j-1]+s[i]-s[i1-1]} 不选:f[i][j]=max(f[i][j],...
  • zz_ylolita
  • zz_ylolita
  • 2016-02-10 00:28
  • 1214

[SCOI2005] 最大子矩阵

本题地址http://www.luogu.org/problem/show?pid=2331题目描述这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2,1...
  • QWsin
  • QWsin
  • 2016-06-16 20:42
  • 573

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

动态规划~
  • Regina8023
  • Regina8023
  • 2015-02-21 00:09
  • 456

[BZOJ 1084][SCOI2005]最大子矩阵

Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。 Input 第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过327...
  • qpswwww
  • qpswwww
  • 2014-06-08 20:46
  • 773

BZOJ 1084 [SCOI2005]最大子矩阵

分类DP记mx[i][j]表示[j,i]这一个区间里,必须取i的最大连续子段和,用前缀和pre维护。如果m=1,记f[i][j]表示做到第i行,已经取j个的答案,如果m=2就记f[i][j][k],i和j表示两列分别做到哪一行,已经取k个的答案。#include<cstdio> #inc...
  • ziqian2000
  • ziqian2000
  • 2016-09-25 12:29
  • 90

BZOJ 1084: [SCOI2005]最大子矩阵

Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。 Input 第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值...
  • u013810072
  • u013810072
  • 2014-08-10 21:14
  • 463

BZOJ P1084[scoi2005]最大子矩阵

随手翻到了之前做的一道水题,随便写篇题解水一水吧 最大子矩阵,一开始不会,一度以为是神题(划掉) 然后发现m m==1时 直接求序列分成k段的最大和 m==2时 f[i][j][k]表示上一行还有i个数,下一行还有j个数时取k个子矩阵的最大和 下面是代码(能AC我吃羊羽) #incl...
  • mdnd1234
  • mdnd1234
  • 2017-03-13 11:21
  • 92

bzoj 1084: [SCOI2005]最大子矩阵

当m=1的时候就是个简单的k个最大子段和就不说了 dp[i][j][k]表示第1列取到前i个数,第2列取到前j个数,共用了k个矩阵所得到的最大值
  • Jaihk662
  • Jaihk662
  • 2017-06-28 15:56
  • 171

BZOJ 1084 SCOI2005 最大子矩阵 动态规划

题目大意:给出一个矩阵,求在这个矩阵中取出k个不重叠的矩阵的最大和。 思路:怎么做? 这个问题困扰我好几天的时间,终于再一次读题: 。。。 。。 。。。 2??!! 这尼玛逗我??直接说最多两列不好么?还用矩阵吓唬我? 好吧下次我一定认真看题。。 我的做法比较渣,算...
  • jiangyuze831
  • jiangyuze831
  • 2014-11-19 13:30
  • 1098

[bzoj 1086--SCOI2005]王室联邦

Description   有n个点,n-1条边,任意两个不同的点之间有且仅有一条直接或间接边。把n个点分为若干个部分,每个部分最少要b个点,其中有一个点(BOSS)可在此部分内或外。使得此部分内的点到BOSS点的路径上经过的点全在此部分内。
  • lixuanjing2016
  • lixuanjing2016
  • 2016-08-26 11:44
  • 341
    个人资料
    • 访问:8058次
    • 积分:461
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:1篇
    • 译文:0篇
    • 评论:13条
    膜拜大(蒟)牛(蒻)
    game
    最新评论