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

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

    有一个1A~~~

    本题没看懂,,不会啊囧。。感觉完全设不了状态。。看了题解,囧,m<=2,没看到的。。默哀吧。然后此题就很好设方程了,m=1时是链,单独考虑,m=2时,考虑几种情况:

    m==1时:

    设d[i][j]表示前i个元素j个矩阵的最大值,有

    d[i][j]=max(d[i-1][j], d[k][j-1]+sum[i]-sum[k], 0<=k<i)

    很好理解。。。

    m==2时:

    设d[i][j][k]表示列1的前i个元素和列2前j个元素k个矩阵的最大值,有:

    d[i][j][k]=max(d[i-1][j][k], d[i][j-1][k])

    d[i][j][k]=max(d[x][j][k-1]+sum1[i]-sum1[x], 0<=x<i)

    d[i][j][k]=max(d[i][x][k-1]+sum2[j]-sum2[x], 0<=x<j)

    当i==j时,d[i][j][k]=max(d[x][x][k-1]+sum1[i]-sum1[x]+sum2[j]-sum2[x], 0<=x<i)

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define read(a) a=getnum()
    #define print(a) printf("%d", a)
    inline int getnum() { int ret=0; char c; int k=1; for(c=getchar(); c<'0' || c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0' && c<='9'; c=getchar()) ret=ret*10+c-'0'; return ret*k; }
    
    const int N=105;
    int f[N][N][15], s[N][5], ans, d[N][15];
    
    int main() {
    	int n=getnum(), m=getnum(), K=getnum();
    	for1(i, 1, n) for1(j, 1, m) s[i][j]=s[i-1][j]+getnum();
    	if(m==1) {
    		for1(i, 1, n) for1(j, 1, K) {
    			d[i][j]=d[i-1][j];
    			for1(k, 0, i-1) d[i][j]=max(d[i][j], d[k][j-1]+s[i][1]-s[k][1]);
    		}
    		ans=d[n][K];
    	}
    	else {
    		for1(i, 1, n) for1(j, 1, n) for1(k, 1, K) {
    			f[i][j][k]=max(f[i-1][j][k], f[i][j-1][k]);
    			for1(l, 0, i-1)
    				f[i][j][k]=max(f[i][j][k], f[l][j][k-1]+s[i][1]-s[l][1]);
    			for1(l, 0, j-1)
    				f[i][j][k]=max(f[i][j][k], f[i][l][k-1]+s[j][2]-s[l][2]);
    			if(i==j) for1(l, 0, i-1)
    				f[i][j][k]=max(f[i][j][k], f[l][l][k-1]+s[i][1]-s[l][1]+s[j][2]-s[l][2]);
    		}
    		ans=f[n][n][K];
    	}
    	print(ans);
    	return 0;
    }
    

    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

    Source

  • 相关阅读:
    .NET简谈互操作(七:数据封送之介绍)
    C# utf8编码时转换成shiftjis时出现乱码问题的处理
    .NET简谈特性(代码属性)
    著名Channel 9 主持人Robert Green 采访微软一站式示例代码库录像
    SharePoint 2007运行 Edit In DataSheet 时在IE 6下页面卡死的分析和处理方法
    截图工具
    Resharper上手指南
    .NET简谈互操作(三:基础知识之DllImport特性)
    .NET简谈互操作(五:基础知识之提升平台调用性能)
    深度训练(DotNet专场)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3887654.html
Copyright © 2011-2022 走看看