SCOI2005]最大子矩阵(dp)

[SCOI2005]最大子矩阵

https://ac.nowcoder.com/acm/problem/20242

一开始思路错了,想着把k当成1 求了一个最大子矩阵
然后对最大子矩阵所在的一行用最大k段子序列,后来发现思路错了,因为这样所求的子矩阵的终点行一定都相同了
正确的思路
因为m(列)是1<=m<=2,只有两种情况,对于m==1时候就是个竖着的最大k段子序列的和,

        dp[i][x][y]
        在第一列的1-x行选择
        在第二列的1-y行选择
        共选择i个矩阵
        1.假如选择第(x,1) 不选(y,2) max(dp[i-1][t][y]+a[x][1]-a[t-1][1],dp[i][x][y] )
        2.假如不选择第(x,1) 选(y,2)max(dp[i-1][x][t]+a[y][2]-a[t-1][2],dp[i][x][y] )
        3.假如选择第(x,1) 选(y,2)max(dp[i-1][t][t]+a[x][1]-a[t-1][1]+a[y][2]-a[t-1][2],dp[i][x][y] )

代码

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio>
#include <bitset>
#include <vector>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define UpMing main
#define re register
#pragma GCC optimize(2)
#define Accept return 0;
#define lowbit(x) ((x)&(-(x)))
#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int inf =0x3f3f3f3f;
const int maxn=2e5+66;
const ll mod = 911451407;
const int N =1e6+3;
inline ll read() {
    ll  x=0;
    bool f=0;
    char ch=getchar();
    while (ch<'0'||'9'<ch)    f|=ch=='-', ch=getchar();
    while ('0'<=ch && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
void out(ll x) {
    int stackk[20];
    if(x<0) {
        putchar('-');
        x=-x;
    }
    if(!x) {
        putchar('0');
        return;
    }
    int top=0;
    while(x) stackk[++top]=x%10,x/=10;
    while(top) putchar(stackk[top--]+'0');
}
ll n,m,k,a[121][121],b[121],pre[121],dp[121][121][121],d[121],s[1212][125];
int UpMing() {
    n=read(),m=read(),k=read();
    rep(i,1,n) rep(j,1,m) s[i][j]=a[i][j]=read(),a[i][j]+=a[i-1][j];
    if(m==1) {
        for(int i=1 ; i<=n ; i++)
            b[i]=s[i][1],b[i]+=b[i-1];

        mst(s,0);
        for(int i=1 ; i<=k ; i++) {
            for(int j=1 ; j<=n ; j++) {
                for(int t=0 ; t<j ; t++) {
                    s[i][j]=max(s[i][j-1],s[i][j]);
                    s[i][j]=max(s[i][j],s[i-1][t]+b[j]-b[t]);
                }
            }
        }

    } else {
        for(int i=1 ; i<=k ; i++) {
            for(int j=1; j<=n ; j++) {
                for(int t=1 ; t<=n ; t++) {
                    dp[i][j][t]=max(max(dp[i][j-1][t],dp[i][j][t-1]),dp[i][j-1][t-1]);
                    for(int p=0 ; p<j; p++)    dp[i][j][t]=max(dp[i][j][t],dp[i-1][p][t]+a[j][1]-a[p][1]);
                    for(int p=0 ; p<t; p++)    dp[i][j][t]=max(dp[i][j][t],dp[i-1][j][p]+a[t][2]-a[p][2]);
                    if(j==t) for(int p=0 ; p<j; p++) dp[i][j][t]=max(dp[i][j][t],dp[i-1][p][p]+a[j][1]-a[p][1]+a[t][2]-a[p][2]);
                }
            }
        }
        out(dp[k][n][n]);
    }

    Accept;
}

m==1时候优化算法


#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio>
#include <bitset>
#include <vector>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define UpMing main
#define re register
#pragma GCC optimize(2)
#define Accept return 0;
#define lowbit(x) ((x)&(-(x)))
#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int inf =0x3f3f3f3f;
const int maxn=2e5+66;
const ll mod = 911451407;
const int N =1e6+3;
inline ll read() {
    ll  x=0;
    bool f=0;
    char ch=getchar();
    while (ch<'0'||'9'<ch)    f|=ch=='-', ch=getchar();
    while ('0'<=ch && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return f?-x:x;
}
void out(ll x) {
    int stackk[20];
    if(x<0) {
        putchar('-');
        x=-x;
    }
    if(!x) {
        putchar('0');
        return;
    }
    int top=0;
    while(x) stackk[++top]=x%10,x/=10;
    while(top) putchar(stackk[top--]+'0');
}
ll n,m,k,a[121][121],b[121],pre[121],dp[121][121][121],d[121],s[1212][125];
int UpMing() {
    n=read(),m=read(),k=read();
    rep(i,1,n) rep(j,1,m) s[i][j]=a[i][j]=read(),a[i][j]+=a[i-1][j];
    if(m==1) {
        for(int i=1 ; i<=n ; i++)
            b[i]=s[i][1];

            ll temp;
            for(int i=1 ; i<=k ; i++) {
                temp=-inf;
                for(int j=i ; j<=n ; j++) {
                    d[j]=max(d[j-1],pre[j-1])+b[j];
                    pre[j-1]=temp;
                    temp=max(temp,d[j]);
                }
            }
            cout<<temp<<endl;

    } else {
        for(int i=1 ; i<=k ; i++) {
            for(int j=1; j<=n ; j++) {
                for(int t=1 ; t<=n ; t++) {
                    dp[i][j][t]=max(max(dp[i][j-1][t],dp[i][j][t-1]),dp[i][j-1][t-1]);
                    for(int p=0 ; p<j; p++)  dp[i][j][t]=max(dp[i][j][t],dp[i-1][p][t]+a[j][1]-a[p][1]);
                    for(int p=0 ; p<t; p++)  dp[i][j][t]=max(dp[i][j][t],dp[i-1][j][p]+a[t][2]-a[p][2]);
                    if(j==t) for(int p=0 ; p<j; p++) dp[i][j][t]=max(dp[i][j][t],dp[i-1][p][p]+a[j][1]-a[p][1]+a[t][2]-a[p][2]);
                }
            }
        }
        out(dp[k][n][n]);
    }

    Accept;
}
全部评论
orz
1 回复 分享
发布于 2020-06-07 15:58
%%%
1 回复 分享
发布于 2020-06-07 15:58
禁止自娱自乐
1 回复 分享
发布于 2020-06-07 15:58
嘻嘻嘻
1 回复 分享
发布于 2020-06-07 15:59
or2
点赞 回复 分享
发布于 2020-06-08 08:07
%%%
点赞 回复 分享
发布于 2020-06-08 08:07
禁止自娱自乐
点赞 回复 分享
发布于 2020-06-08 08:07
嘻嘻嘻
点赞 回复 分享
发布于 2020-06-08 08:07

相关推荐

评论
1
收藏
分享
牛客网
牛客企业服务