zoukankan      html  css  js  c++  java
  • BZOJ 1084: [SCOI2005]最大子矩阵 DP

    1084: [SCOI2005]最大子矩阵

    题目连接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1084

    Description

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

    Input

    第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。

    Output

    只有一行为k个子矩阵分值之和最大为多少。

    Sample Input

    3 2 2

    1 -3

    2 3

    -2 3

    Sample Output

    9

    Hint

    题意

    题解:

    首先我们注意m只有2

    所以我们分开考虑即可,m=1的时候,dp[i][k]表示考虑第i个,分割了k块的最大值,然后无脑转移就好了

    m=2的时候也是一样的,dp[i][j][k]表示上面考虑到第i个,下面考虑到了第j个,分割了k块

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m,k;
    int sum1[120];
    int sum2[120];
    int dp1[120][12];
    int dp2[120][120][12];
    void solve1()
    {
        for(int i=1;i<=n;i++)
        {
            int x;scanf("%d",&x);
            sum1[i]=sum1[i-1]+x;
        }
        for(int i=1;i<=n;i++)
            for(int j=0;j<i;j++)
                for(int t=1;t<=k;t++)
                {
                    dp1[i][t]=max(dp1[i][t],dp1[j][t-1]+sum1[i]-sum1[j]);
                    dp1[i][t]=max(dp1[i][t],dp1[j][t]);
                }
        printf("%d
    ",dp1[n][k]);
    }
    void solve2()
    {
        for(int i=1;i<=n;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            sum1[i]=sum1[i-1]+x;
            sum2[i]=sum2[i-1]+y;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i==j)
                {
                    for(int x=0;x<i;x++)
                    {
                        for(int t=1;t<=k;t++)
                        {
                            dp2[i][j][t]=max(dp2[i][j][t],dp2[x][x][t-1]+sum1[i]-sum1[x]+sum2[i]-sum2[x]);
                            dp2[i][j][t]=max(dp2[i][j][t],dp2[x][x][t]);
                        }
                    }
                }
                for(int i2=0;i2<i;i2++)
                {
                    for(int t=1;t<=k;t++)
                    {
                        dp2[i][j][t]=max(dp2[i][j][t],dp2[i2][j][t-1]+sum1[i]-sum1[i2]);
                        dp2[i][j][t]=max(dp2[i][j][t],dp2[i2][j][t]);
                    }
                }
                for(int j2=0;j2<j;j2++)
                {
                    for(int t=1;t<=k;t++)
                    {
                        dp2[i][j][t]=max(dp2[i][j][t],dp2[i][j2][t-1]+sum2[j]-sum2[j2]);
                        dp2[i][j][t]=max(dp2[i][j][t],dp2[i][j2][t]);
                    }
                }
            }
        }
        printf("%d
    ",dp2[n][n][k]);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        if(m==1)solve1();
        if(m==2)solve2();
    }
  • 相关阅读:
    javaweb学习2
    javaweb学习1
    Java学习17
    python 正则表达式
    python 常用库
    python 常用内置函数
    python 函数高级功能
    python 正则表达式findall
    tcpdump
    安卓软件学习进度_1
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5179879.html
Copyright © 2011-2022 走看看